#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <conio.h>
#include <math.h>
#include <dir.h>
#include "defs.h"
#include "kernel.h"
#include "utils.h"
#include "setup.h"
#include "help.h"

void setup(struct hard_setup *hard_config, struct soft_setup *soft_config)
{
   int ch, curnt=0, i, change=FALSE;
   char temp1[20]={1}, temp2[20]={2};
   static char item[9][35]={"Port Settings","Bit Settings","Unit, Label, Jog, and F/R Settings",
                             "Calibration Settings","Home and Limit Switch Settings",
                             "Load Default Settings","Save As","Save", "Exit (ask for save)"};
   static BYTE screen[2000], buffer[1000];
   static struct hard_setup hardware;
   static struct soft_setup software;
   struct find_t ffblk;

   hardware=*hard_config; software=*soft_config;
   load_setup(&hardware, &software, software.file);
   gettext(21,1,60,25,screen);
   textcolor(BLUE);
   _setcursortype(_NOCURSOR);
   while(1)
     {window(21,1,60,25);
      textbackground(CYAN);
      clrscr();
      box(21,3,60,15, CYAN,BLACK,WHITE,BLACK);
      window(21,1,60,25);
      gotoxy(15,1); cprintf("<Esc> To Exit");
      gotoxy(4,3); cprintf("Cfg: %s",software.file);
      for(i=0;i<9;i++) {gotoxy(4,i+5); cprintf("%s",item[i]);}
      while (1)
        {textcolor(WHITE); gotoxy(4,curnt+5); textbackground(BLUE);
         cprintf("%s",item[curnt]); ch=getch();

			textcolor(BLACK);
         gotoxy(4,curnt+5); textbackground(CYAN);
         cprintf("%s",item[curnt]);
         if (ch == 13 || ch == 32) {if(strcmp(software.file,"<DEFAULT>")==0 && curnt==7) curnt=6; break;}
         if (ch == 27) {curnt=8; break;}
         if (ch > 0) continue;
         ch = getch();

         switch (ch)
           {case 72 : if(curnt>0)--curnt; break;                //up arrow
            case 80 : if(curnt<8)++curnt; break;                //down arrow
            case 59 : help(curnt+2); break;                     //f1
            case 81 : curnt=8; break;                           //pg dn
            case 73 : curnt=0; break;                           //pg up
            }
        }

      START:
      switch(curnt)
        {case 0:
            if(pins(&hardware)) change=TRUE;
            break;
         case 1:
            if(bits(&hardware, &software)) change=TRUE;
            break;
         case 2:
            if(label(&hardware, &software)) change=TRUE;
            break;
         case 3:
            if(calibration(&hardware, &software)) change=TRUE;
            break;
         case 4:
            if(home(&hardware, &software)) change=TRUE;
            break;
         case 5:
            box(22,17,59,22, RED,BLACK,WHITE,WHITE);
            gotoxy(4,3); cprintf("     Load Default Settings");
            gotoxy(4,4); cprintf("<Enter> To Accept  <Esc> To Abort");
            while(1)
              {ch=getch();
               if(ch==27 || ch==13 || ch==32) break;
              }
            if(ch==27) break;
            sprintf(temp1,"%s",software.password);
            sprintf(temp2,"%s",software.file);
            load_setup(&hardware, &software, "<DEFAULT>");
            sprintf(software.password,"%s",temp1);
            sprintf(software.file,"%s",temp2);
            change=TRUE;
            break;
         case 6:
            box(27,17,52,23, RED,BLACK,WHITE,WHITE);
            gotoxy(4,4); cprintf("Save As:");
            window(39,20,47,20);
            textbackground(BLACK);
            clrscr();
            gotoxy(1,1);
            _setcursortype(_NORMALCURSOR);
            while(NULL==(i=get_string(temp1, NULL)));
            _setcursortype(_NOCURSOR);
            if(i==ESC) break;
            i=0;
            sprintf(temp2,"%s.CFG",temp1);
            if(chdir("CONFIG")!=0) {mkdir("CONFIG"); chdir("CONFIG");}
            if(_dos_findfirst(temp2,_A_NORMAL,&ffblk)==NULL)
              {gettext(22,17,59,22,buffer);
               box(22,17,59,22, RED,BLACK,WHITE,WHITE);
               gotoxy(4,3); cprintf("   Replace File: %s?", temp2);
               gotoxy(4,4); cprintf("<Enter> To Accept  <Esc> To Abort");
               while(1) {i=getch(); if(i==27 || i==13 || i==32) break;}
               puttext(22,17,59,22,buffer);
              }
            chdir("..");
            if(i==27) break;
            _setcursortype(_NOCURSOR);
            sprintf(software.file,"%s",temp2);
         case 7:
            if(curnt==7)
              {box(22,17,59,22, RED,BLACK,WHITE,WHITE);
               gotoxy(4,3); cprintf("   Save File To: %s",software.file);
               gotoxy(4,4); cprintf("<Enter> To Accept  <Esc> To Abort");
               while(1)
                 {ch=getch();
                  if(ch==27 || ch==13 || ch==32) break;}
               if(ch==27) break;
              }
            *hard_config=hardware;
            *soft_config=software;
            save_setup(hard_config, soft_config, (*soft_config).file);
            change=FALSE;
            break;
         case 8:
            if(change==TRUE)
              {box(22,16,59,23, RED,BLACK,WHITE,WHITE);

               gotoxy(4,3); cprintf("      UnSaved Changes made  ");
               gotoxy(4,4); cprintf("                            ");
               gotoxy(4,5); cprintf("     <Enter> To Quit Anyway ");
               gotoxy(4,6); cprintf("      <Esc> To Cancel Quit  ");

               while(1)
                 {ch=getch();
                  if (ch==13) break;
                  else
                  if (ch==27) curnt=6;
                        box(22,16,59,23, CYAN,CYAN,CYAN,CYAN);
                      goto START;}
              }
            puttext(21,1,60,25,screen);
            return;
        }
     }
}

int pins(struct hard_setup *hardware)
{
   int ch, i, temp, curnt=0, curnt2, tab=0,  val, change=FALSE;
   int x[4][8]={{4},{4,4,4,4,4,4,4,4},{24,24,24,24,24},{24,24,24,24}};
   int y[4][8]={{12},{16,17,18,19,20,21,22,23},{12,13,14,15,16},{20,21,22,23}};
   static char item[4][8][30];
   static char item2[4][8][15];
   static struct hard_setup temp_config;
   window(21,1,60,25);
   textbackground(CYAN);
   clrscr();
   for(i=0;i<8;i++) sprintf(item2[1][i],"Pin        %2d",i+2);
   sprintf(item2[0][0],"Port     0x378");
   sprintf(item2[0][1],"Port     0x278");
   sprintf(item2[0][2],"Port     0x3BC");
   sprintf(item2[3][0],"Pin          1");
   sprintf(item2[3][1],"Pin         14");
   sprintf(item2[3][2],"Pin         16");
   sprintf(item2[3][3],"Pin         17");
   for(i=0;i<4;i++) sprintf(item2[2][i],"Pin         %2d",i+10);
   sprintf(item2[2][4],"Pin         15");

   box(21,2,60,9, CYAN,BLACK,WHITE,BLACK);
   gotoxy(4,3); cprintf(" 13-----------------------------1");
   gotoxy(4,4); cprintf("   \\                           /");
   gotoxy(4,5); cprintf("    \\                         /");
   gotoxy(4,6); cprintf("   25-------------------------14");
   textcolor(YELLOW);
   gotoxy(9,4); cprintf("o o o o o o o o o o o o o");
   textcolor(BLACK);
   gotoxy(10,5); cprintf("o o o o o o o o");
   textcolor(YELLOW);
   cprintf(" o o o o");
   textcolor(WHITE);
   gotoxy(3,8); cprintf("Looking at Port on Back of Computer");
   window(21,1,60,25);
   gotoxy(1,1); cprintf(" <Tab> To Change group    <Esc> To Exit");
	textcolor(BLACK);

   while (1)
     {sprintf(item[1][0],"<X> Step Pin %d",data_pin((*hardware).x_sbit));
      sprintf(item[1][1],"<X> Dir Pin  %d",data_pin((*hardware).x_dbit));
      sprintf(item[1][2],"<Y> Step Pin %d",data_pin((*hardware).y_sbit));
      sprintf(item[1][3],"<Y> Dir Pin  %d",data_pin((*hardware).y_dbit));
      sprintf(item[1][4],"<Z> Step Pin %d",data_pin((*hardware).z_sbit));
      sprintf(item[1][5],"<Z> Dir Pin  %d",data_pin((*hardware).z_dbit));
      sprintf(item[1][6],"<Aux>St. Pin %d",data_pin((*hardware).a_sbit));
      sprintf(item[1][7],"<Aux>Dir Pin %d",data_pin((*hardware).a_dbit));
      if((*hardware).port==0x378) sprintf(item[0][0],"Port     0X378");
      if((*hardware).port==0x278) sprintf(item[0][0],"Port     0X278");
      if((*hardware).port==0x3bc) sprintf(item[0][0],"Port     0X3BC");
      sprintf(item[3][0],"<1st IO>Pin %2d",control_pin((*hardware).io1_bit));
      sprintf(item[3][1],"<2nd IO>Pin %2d",control_pin((*hardware).io2_bit));
      sprintf(item[3][2],"<3rd IO>Pin %2d",control_pin((*hardware).io3_bit));
      sprintf(item[3][3],"<4th IO>Pin %2d",control_pin((*hardware).io4_bit));
      sprintf(item[2][0],"<X>Lim Pin  %2d",status_pin((*hardware).x_lbit));
      sprintf(item[2][1],"<Y>Lim Pin  %2d",status_pin((*hardware).y_lbit));
      sprintf(item[2][2],"<Z>Lim Pin  %2d",status_pin((*hardware).z_lbit));
      sprintf(item[2][3],"<Aux>LimPin %2d",status_pin((*hardware).a_lbit));
      sprintf(item[2][4],"<ES/Hld>Pin %2d",status_pin((*hardware).e_bit));

      box(21,10,40,14, CYAN,BLACK,WHITE,BLACK);
      box(21,14,40,25, CYAN,BLACK,WHITE,BLACK);
      box(41,10,60,18, CYAN,BLACK,WHITE,BLACK);
      box(41,18,60,25, CYAN,BLACK,WHITE,BLACK);
      window(21,1,60,25);
      for(i=0;i<8;i++) {gotoxy(x[1][i],y[1][i]); cprintf("%s",item[1][i]);}
      gotoxy(x[0][0],y[0][0]); cprintf("%s",item[0][0]);
      for(i=0;i<4;i++) {gotoxy(x[3][i],y[3][i]); cprintf("%s",item[3][i]);}
      for(i=0;i<5;i++) {gotoxy(x[2][i],y[2][i]); cprintf("%s",item[2][i]);}
      while (1)
        {textcolor(WHITE); gotoxy(x[tab][curnt],y[tab][curnt]); textbackground(BLUE);
         cprintf("%s",item[tab][curnt]); ch=getch();
         textcolor(BLACK);
         if (ch == 13 || ch == 32)
           {gotoxy(x[tab][curnt],y[tab][curnt]); textbackground(GREEN);
            cprintf("%s",item[tab][curnt]); textbackground(CYAN);
            change=TRUE;
            break;
           }
         gotoxy(x[tab][curnt],y[tab][curnt]); textbackground(CYAN);
         cprintf("%s",item[tab][curnt]);
         if (ch == 27) return change;
         if (ch == 9) {tab++; curnt=0; if(tab==4) tab=0;}
         if (ch > 0) continue;
         ch = getch();
         switch (ch)
           {case 72 : --curnt; break;  //up arrow
            case 80 : ++curnt; break;  //down arrow
            case 59 : help(tab+12); break;  //f1
            case 81 : curnt=8; break;  //pg dn
            case 73 : curnt=0; break;  //pg up
           }
         if(tab==0){if(curnt<0) curnt=0; if(curnt>0) curnt=0;}
         if(tab==1){if(curnt<0) curnt=0; if(curnt>7) curnt=7;}
         if(tab==2){if(curnt<0) curnt=0; if(curnt>4) curnt=4;}
         if(tab==3){if(curnt<0) curnt=0; if(curnt>3) curnt=3;}
        }
      if(tab==0 || tab==1) double_box(41,11,60,24, CYAN,WHITE,BLUE);
      else double_box(21,11,40,24, CYAN,WHITE,BLUE);
      curnt2=0;
      if(tab==1) for(i=3;i<11;i++) {gotoxy(4,i); cprintf("%s",item2[1][i-3]);}
      if(tab==0) for(i=3;i<6;i++) {gotoxy(4,i); cprintf("%s",item2[0][i-3]);}
      if(tab==3) for(i=3;i<7;i++) {gotoxy(4,i); cprintf("%s",item2[3][i-3]);}
      if(tab==2) for(i=3;i<8;i++) {gotoxy(4,i); cprintf("%s",item2[2][i-3]);}
      while (1)
        {textcolor(WHITE); gotoxy(4,curnt2+3); textbackground(BLUE);
         cprintf("%s",item2[tab][curnt2]); ch=getch();
         textcolor(BLACK);
         gotoxy(4,curnt2+3); textbackground(CYAN);
         cprintf("%s",item2[tab][curnt2]);
         if (ch == 13 || ch == 32) break;
         if (ch == 27) break;
         if (ch > 0) continue;
         ch = getch();
         switch (ch)
           {case 72 : --curnt2; break;  //up arrow
            case 80 : ++curnt2; break;  //down arrow
            case 81 : curnt2=8; break;  //pg dn
            case 73 : curnt2=0; break;  //pg up
           }
         if(tab==1){if(curnt2<0) curnt2=0; if(curnt2>7) curnt2=7;}
         if(tab==0){if(curnt2<0) curnt2=0; if(curnt2>2) curnt2=2;}
         if(tab==3){if(curnt2<0) curnt2=0; if(curnt2>3) curnt2=3;}
         if(tab==2){if(curnt2<0) curnt2=0; if(curnt2>4) curnt2=4;}
        }
      temp_config=*hardware;
      if(ch!=27)
        switch(tab)
           {case 1:
               if(curnt2==0) val=1;
               if(curnt2==1) val=2;
               if(curnt2==2) val=4;
               if(curnt2==3) val=8;
               if(curnt2==4) val=16;
               if(curnt2==5) val=32;
               if(curnt2==6) val=64;
               if(curnt2==7) val=128;

               if(curnt==0) {temp=(*hardware).x_sbit; (*hardware).x_sbit=val;}
               if(curnt==1) {temp=(*hardware).x_dbit; (*hardware).x_dbit=val;}
               if(curnt==2) {temp=(*hardware).y_sbit; (*hardware).y_sbit=val;}
               if(curnt==3) {temp=(*hardware).y_dbit; (*hardware).y_dbit=val;}
               if(curnt==4) {temp=(*hardware).z_sbit; (*hardware).z_sbit=val;}
               if(curnt==5) {temp=(*hardware).z_dbit; (*hardware).z_dbit=val;}
               if(curnt==6) {temp=(*hardware).a_sbit; (*hardware).a_sbit=val;}
               if(curnt==7) {temp=(*hardware).a_dbit; (*hardware).a_dbit=val;}

               if(val==temp_config.x_sbit) (*hardware).x_sbit=temp;
               if(val==temp_config.x_dbit) (*hardware).x_dbit=temp;
               if(val==temp_config.y_sbit) (*hardware).y_sbit=temp;
               if(val==temp_config.y_dbit) (*hardware).y_dbit=temp;
               if(val==temp_config.z_sbit) (*hardware).z_sbit=temp;
               if(val==temp_config.z_dbit) (*hardware).z_dbit=temp;
               if(val==temp_config.a_sbit) (*hardware).a_sbit=temp;
               if(val==temp_config.a_dbit) (*hardware).a_dbit=temp;
               break;
            case 0:
               if(curnt2==0) (*hardware).port=0x378;
               if(curnt2==1) (*hardware).port=0x278;
               if(curnt2==2) (*hardware).port=0x3bc;
               break;
            case 3:
               if(curnt2==0) val=1;
               if(curnt2==1) val=2;
               if(curnt2==2) val=4;
               if(curnt2==3) val=8;

               if(curnt==0) {temp=(*hardware).io1_bit; (*hardware).io1_bit=val;}
               if(curnt==1) {temp=(*hardware).io2_bit; (*hardware).io2_bit=val;}
               if(curnt==2) {temp=(*hardware).io3_bit; (*hardware).io3_bit=val;}
               if(curnt==3) {temp=(*hardware).io4_bit; (*hardware).io4_bit=val;}

               if(val==temp_config.io1_bit) (*hardware).io1_bit=temp;
               if(val==temp_config.io2_bit) (*hardware).io2_bit=temp;
               if(val==temp_config.io3_bit) (*hardware).io3_bit=temp;
               if(val==temp_config.io4_bit) (*hardware).io4_bit=temp;
               break;
            case 2:
               if(curnt2==0) val=64;
               if(curnt2==1) val=128;
               if(curnt2==2) val=32;
               if(curnt2==3) val=16;
               if(curnt2==4) val=8;

               if(curnt==0) {temp=(*hardware).x_lbit; (*hardware).x_lbit=val;}
               if(curnt==1) {temp=(*hardware).y_lbit; (*hardware).y_lbit=val;}
               if(curnt==2) {temp=(*hardware).z_lbit; (*hardware).z_lbit=val;}
               if(curnt==3) {temp=(*hardware).a_lbit; (*hardware).a_lbit=val;}
               if(curnt==4) {temp=(*hardware).e_bit; (*hardware).e_bit=val;}

               if(val==temp_config.x_lbit) (*hardware).x_lbit=temp;
               if(val==temp_config.y_lbit) (*hardware).y_lbit=temp;
               if(val==temp_config.z_lbit) (*hardware).z_lbit=temp;
               if(val==temp_config.a_lbit) (*hardware).a_lbit=temp;
               if(val==temp_config.e_bit) (*hardware).e_bit=temp;
               break;
           }
     }
}

int bits(struct hard_setup *hardware, struct soft_setup *software)
{
   static char item[18][35];
   int ch, i, curnt=0, change=FALSE;

   window(21,1,60,25);
   textbackground(CYAN);
   clrscr();
   box(21,1,60,22, CYAN,BLACK,WHITE,BLACK);
   window(21,1,60,25);
   gotoxy(15,1); cprintf("<Esc> To Exit");
   while(1)
     {if((*hardware).x_pdir==HIGH)
           sprintf(item[0], "<X> Positive Direction        HIGH");
      else sprintf(item[0], "<X> Positive Direction         LOW");
      if((*hardware).y_pdir==HIGH)
           sprintf(item[1], "<Y> Positive Direction        HIGH");
      else sprintf(item[1], "<Y> Positive Direction         LOW");
      if((*hardware).z_pdir==HIGH)
           sprintf(item[2], "<Z> Positive Direction        HIGH");
      else sprintf(item[2], "<Z> Positive Direction         LOW");
      if((*software).a_status==ON)
           sprintf(item[3], "Auxiliary Axis                  ON");
      else sprintf(item[3], "Auxiliary Axis                 OFF");
      if((*software).a_follow==INDEPENDANT)
           sprintf(item[4], "Auxiliary Axis         INDEPENDENT");
      if((*software).a_follow==FOLLOW_X)
           sprintf(item[4], "Auxiliary Axis          FOLLOW <X>");
      if((*software).a_follow==FOLLOW_Y)
           sprintf(item[4], "Auxiliary Axis          FOLLOW <Y>");
      if((*software).a_follow==FOLLOW_Z)
           sprintf(item[4], "Auxiliary Axis          FOLLOW <Z>");
      if((*hardware).a_pdir==HIGH)
           sprintf(item[5], "<Aux> Positive Direction      HIGH");
      else sprintf(item[5], "<Aux> Positive Direction       LOW");
      if((*software).limit==ON)
           sprintf(item[6], "Limit Switches                  ON");
      else sprintf(item[6], "Limit Switches                 OFF");
      if((*hardware).x_ltrip==HIGH)
           sprintf(item[7], "<X> Limit Switch Activate     HIGH");
      else sprintf(item[7], "<X> Limit Switch Activate      LOW");
      if((*hardware).y_ltrip==HIGH)
           sprintf(item[8], "<Y> Limit Switch Activate     HIGH");
      else sprintf(item[8], "<Y> Limit Switch Activate      LOW");
      if((*hardware).z_ltrip==HIGH)
           sprintf(item[9], "<Z> Limit Switch Activate     HIGH");
      else sprintf(item[9], "<Z> Limit Switch Activate      LOW");
      if((*hardware).a_ltrip==HIGH)
           sprintf(item[10],"<Aux> Limit Switch Activate   HIGH");
      else sprintf(item[10],"<Aux> Limit Switch Activate    LOW");
      if((*software).e_stop==E_STOP_L)
           sprintf(item[11],"E-Stop/Hold Line            E-STOP");
      else if((*software).e_stop==HOLD_L)
           sprintf(item[11],"E-Stop/Hold Line         HOLD LINE");
      else sprintf(item[11],"E-Stop/Hold Line               OFF");
      if((*hardware).e_trip==HIGH)
           sprintf(item[12],"E-Stop/Hold Line Activate     HIGH");
      else sprintf(item[12],"E-Stop/Hold Line Activate      LOW");
      if((*hardware).io1_on==HIGH)
           sprintf(item[13],"<1st IO> Enable               HIGH");
      else sprintf(item[13],"<1st IO> Enable                LOW");
      if((*hardware).io2_on==HIGH)
           sprintf(item[14],"<2nd IO> Enable               HIGH");
      else sprintf(item[14],"<2nd IO> Enable                LOW");
      if((*hardware).io3_on==HIGH)
           sprintf(item[15],"<3rd IO> Enable               HIGH");
      else sprintf(item[15],"<3rd IO> Enable                LOW");
      if((*hardware).io4_on==HIGH)
           sprintf(item[16],"<4th IO> Enable               HIGH");
      else sprintf(item[16],"<4th IO> Enable                LOW");
      if((*hardware).act_step==HIGH)
           sprintf(item[17],"Step Bit Transition    LOW TO HIGH");
      else sprintf(item[17],"Step Bit Transition    HIGH TO LOW");

      for(i=0;i<18;i++) {gotoxy(4,i+3); cprintf("%s",item[i]);}
      while (1)
        {textcolor(WHITE); gotoxy(4,curnt+3); textbackground(BLUE);
         cprintf("%s",item[curnt]); ch=getch();
         textcolor(BLACK);
         if (ch == 13 || ch == 32)
           {gotoxy(4,curnt+3); textbackground(GREEN);
            cprintf("%s",item[curnt]); textbackground(CYAN);
            change=TRUE;
            break;
           }
         gotoxy(4,curnt+3); textbackground(CYAN);
         cprintf("%s",item[curnt]);
         if (ch == 27) return change;
         if (ch > 0) continue;
         ch = getch();
         switch (ch)
           {case 72 : --curnt; break;  //up arrow
            case 80 : ++curnt; break;  //down arrow
            case 81 : curnt=18; break;  //pg dn
            case 73 : curnt=0; break;  //pg up

            case 59 :
              switch(curnt)
                {case 0: case 1: case 2: case 5: help(17); break;
                 case 3: case 4: help(18); break;
                 case 6: help(19); break;
                 case 7: case 8: case 9: case 10: help(20); break;
                 case 11: help(21); break;
                 case 12: help(22); break;
                 case 13: case 14: case 15: case 16: help(23); break;
                 case 17: help(49); break;
                }
           }
         if(curnt<0) curnt=0;
         if(curnt>17) curnt=17;
        }

     switch(curnt)
       {case 0:  if((*hardware).x_pdir==HIGH) (*hardware).x_pdir=LOW;
                 else (*hardware).x_pdir=HIGH; break;
        case 1:  if((*hardware).y_pdir==HIGH) (*hardware).y_pdir=LOW;
                 else (*hardware).y_pdir=HIGH; break;
        case 2:  if((*hardware).z_pdir==HIGH) (*hardware).z_pdir=LOW;
                 else (*hardware).z_pdir=HIGH; break;
        case 3:  if((*software).a_status==OFF)
                   {(*software).a_status=ON;
                    (*software).display_a=ON;
                    (*software).display_as=ON;
                   }
                 else
                   {(*software).a_status=OFF;
                    (*software).display_a=OFF;
                    (*software).display_as=OFF;
                   }
                 break;
        case 4:  if((*software).a_follow==INDEPENDANT) (*software).a_follow=FOLLOW_X;
                 else if((*software).a_follow==FOLLOW_X) (*software).a_follow=FOLLOW_Y;
                 else if((*software).a_follow==FOLLOW_Y) (*software).a_follow=FOLLOW_Z;
                 else if((*software).a_follow==FOLLOW_Z) (*software).a_follow=INDEPENDANT;
                 break;
        case 5:  if((*hardware).a_pdir==HIGH) (*hardware).a_pdir=LOW;
                 else (*hardware).a_pdir=HIGH; break;
        case 6:  if((*software).limit==ON) (*software).limit=OFF;
                 else (*software).limit=ON; break;
        case 7:  if((*hardware).x_ltrip==HIGH) (*hardware).x_ltrip=LOW;
                 else (*hardware).x_ltrip=HIGH; break;
        case 8:  if((*hardware).y_ltrip==HIGH) (*hardware).y_ltrip=LOW;
                 else (*hardware).y_ltrip=HIGH; break;
        case 9:  if((*hardware).z_ltrip==HIGH) (*hardware).z_ltrip=LOW;
                 else (*hardware).z_ltrip=HIGH; break;
        case 10: if((*hardware).a_ltrip==HIGH) (*hardware).a_ltrip=LOW;
                 else (*hardware).a_ltrip=HIGH; break;
        case 11: if((*software).e_stop==E_STOP_L) (*software).e_stop=HOLD_L;
                 else if((*software).e_stop==HOLD_L) (*software).e_stop=OFF;
                 else (*software).e_stop=E_STOP_L; break;
        case 12: if((*hardware).e_trip==HIGH) (*hardware).e_trip=LOW;
                 else (*hardware).e_trip=HIGH; break;
        case 13: if((*hardware).io1_on==HIGH) (*hardware).io1_on=LOW;
                 else (*hardware).io1_on=HIGH; break;
        case 14: if((*hardware).io2_on==HIGH) (*hardware).io2_on=LOW;
                 else (*hardware).io2_on=HIGH; break;
        case 15: if((*hardware).io3_on==HIGH) (*hardware).io3_on=LOW;
                 else (*hardware).io3_on=HIGH; break;
        case 16: if((*hardware).io4_on==HIGH) (*hardware).io4_on=LOW;
                 else (*hardware).io4_on=HIGH; break;
        case 17: if((*hardware).act_step==HIGH) (*hardware).act_step=LOW;
                 else (*hardware).act_step=HIGH; break;
       }
    }
}

int label(struct hard_setup *hardware, struct soft_setup *software)
{  static char item[21][35];
   static char item2[8][15]={"1. X- X+ Y- Y+","2. X- X+ Y+ Y-","3. X+ X- Y- Y+","4. X+ X- Y+ Y-","5. Y- Y+ X- X+","6. Y- Y+ X+ X-","7. Y+ Y- X- X+","8. Y+ Y- X+ X-"};
   int ch, i, curnt=0, curnt2=0, temp, temp1=IN, temp2=DEG, change=FALSE, warning=FALSE;
   char string[10];
   float value;

   while(1)
     {window(21,1,60,25);
      textbackground(CYAN);
      clrscr();
      box(21,1,60,25, CYAN,BLACK,WHITE,BLACK);
      window(21,1,60,25);
      gotoxy(15,1); cprintf("<Esc> To Exit");
      if((*software).time==MIN)
           sprintf(item[0], "Time Units                     MIN");
      else sprintf(item[0], "Time Units                     SEC");
      if((*software).a_time==MIN)
           sprintf(item[1], "<Aux> Time Units               MIN");
      else sprintf(item[1], "<Aux> Time Units               SEC");
      if((*software).units==IN)
           sprintf(item[2], "Units of Measure                IN");
      else sprintf(item[2], "Units of Measure                MM");
      sprintf(item[3],      "<Aux> Label                    '%c'",(*software).a_label);
      if((*software).a_units==IN)
           sprintf(item[4], "<Aux> Units of Measure          IN");
      if((*software).a_units==MM)
           sprintf(item[4], "<Aux> Units of Measure          MM");
      if((*software).a_units==RAD)
           sprintf(item[4], "<Aux> Units of Measure         RAD");
      if((*software).a_units==DEG)
           sprintf(item[4], "<Aux> Units of Measure         DEG");
      sprintf(item[5],"<1st IO> Label               '%3s'",(*software).io1_label);
      sprintf(item[6],"<2nd IO> Label               '%3s'",(*software).io2_label);
      sprintf(item[7],"<3rd IO> Label               '%3s'",(*software).io3_label);
      sprintf(item[8],"<4th IO> Label               '%3s'",(*software).io4_label);

//      if((*software).invert_arrows==ON)
//           sprintf(item[9], "Invert Keyboard Arrows          ON");
//      else sprintf(item[9], "Invert Keyboard Arrows         OFF");

				temp=(*software).invert_arrows;
            temp++;
             sprintf(item[9], "Custom Keyboard Arrows           %d",temp );
//

      if((*software).units==IN)
        {if((*software).time==SEC)
           {  sprintf(item[10],"<X> Fast Jog (IN/SEC)      %s",prn_val((*software).fjog_x));
              sprintf(item[11],"<Y> Fast Jog (IN/SEC)      %s",prn_val((*software).fjog_y));
              sprintf(item[12],"<Z> Fast Jog (IN/SEC)      %s",prn_val((*software).fjog_z));
              sprintf(item[14],"<X> Slow Jog (IN/SEC)      %s",prn_val((*software).sjog_x));
              sprintf(item[15],"<Y> Slow Jog (IN/SEC)      %s",prn_val((*software).sjog_y));
              sprintf(item[16],"<Z> Slow Jog (IN/SEC)      %s",prn_val((*software).sjog_z));
              sprintf(item[18],"F/R Speed Incr (IN/SEC)    %s",prn_val((*software).speed_inc));
           }
         else
           {  sprintf(item[10],"<X> Fast Jog (IN/MIN)      %s",prn_val((*software).fjog_x*60));
              sprintf(item[11],"<Y> Fast Jog (IN/MIN)      %s",prn_val((*software).fjog_y*60));
              sprintf(item[12],"<Z> Fast Jog (IN/MIN)      %s",prn_val((*software).fjog_z*60));
              sprintf(item[14],"<X> Slow Jog (IN/MIN)      %s",prn_val((*software).sjog_x*60));
              sprintf(item[15],"<Y> Slow Jog (IN/MIN)      %s",prn_val((*software).sjog_y*60));
              sprintf(item[16],"<Z> Slow Jog (IN/MIN)      %s",prn_val((*software).sjog_z*60));
              sprintf(item[18],"F/R Speed Incr (IN/MIN)    %s",prn_val((*software).speed_inc*60));
           }
        }
      else
        {if((*software).time==SEC)
           {  sprintf(item[10],"<X> Fast Jog (MM/SEC)      %s",prn_val((*software).fjog_x));
              sprintf(item[11],"<Y> Fast Jog (MM/SEC)      %s",prn_val((*software).fjog_y));
              sprintf(item[12],"<Z> Fast Jog (MM/SEC)      %s",prn_val((*software).fjog_z));
              sprintf(item[14],"<X> Slow Jog (MM/SEC)      %s",prn_val((*software).sjog_x));
              sprintf(item[15],"<Y> Slow Jog (MM/SEC)      %s",prn_val((*software).sjog_y));
              sprintf(item[16],"<Z> Slow Jog (MM/SEC)      %s",prn_val((*software).sjog_z));
              sprintf(item[18],"F/R Speed Incr (MM/SEC)    %s",prn_val((*software).speed_inc));
           }
         else
           {  sprintf(item[10],"<X> Fast Jog (MM/MIN)      %s",prn_val((*software).fjog_x*60));
              sprintf(item[11],"<Y> Fast Jog (MM/MIN)      %s",prn_val((*software).fjog_y*60));
              sprintf(item[12],"<Z> Fast Jog (MM/MIN)      %s",prn_val((*software).fjog_z*60));
              sprintf(item[14],"<X> Slow Jog (MM/MIN)      %s",prn_val((*software).sjog_x*60));
              sprintf(item[15],"<Y> Slow Jog (MM/MIN)      %s",prn_val((*software).sjog_y*60));
              sprintf(item[16],"<Z> Slow Jog (MM/MIN)      %s",prn_val((*software).sjog_z*60));
              sprintf(item[18],"F/R Speed Incr (MM/MIN)    %s",prn_val((*software).speed_inc*60));
           }
        }
      if((*software).a_units==IN)
        {if((*software).a_time==SEC)
           {  sprintf(item[13],"<Aux> Fast Jog (IN/SEC)    %s",prn_val((*software).fjog_a));
              sprintf(item[17],"<Aux> Slow Jog (IN/SEC)    %s",prn_val((*software).sjog_a));
              sprintf(item[19],"<Aux>F/R Sp. Incr (IN/SEC) %s",prn_val((*software).a_speed_inc));
           }
         else
           {  sprintf(item[13],"<Aux> FAST JOG (IN/MIN)    %s",prn_val((*software).fjog_a*60));
              sprintf(item[17],"<Aux> SLOW JOG (IN/MIN)    %s",prn_val((*software).sjog_a*60));
              sprintf(item[19],"<Aux>F/R Sp. Incr (IN/MIN) %s",prn_val((*software).a_speed_inc*60));
           }
        }
      if((*software).a_units==MM)
        {if((*software).a_time==SEC)
           {  sprintf(item[13],"<Aux> Fast Jog (MM/SEC)    %s",prn_val((*software).fjog_a));
              sprintf(item[17],"<Aux> Slow Jog (MM/SEC)    %s",prn_val((*software).sjog_a));
              sprintf(item[19],"F/S <A> SPEED INC (MM/SEC) %s",prn_val((*software).a_speed_inc));
           }
         else
           {  sprintf(item[13],"<Aux> Fast Jog (MM/MIN)    %s",prn_val((*software).fjog_a*60));
              sprintf(item[17],"<Aux> Slow Jog (MM/MIN)    %s",prn_val((*software).sjog_a*60));
              sprintf(item[19],"<Aux>F/R Sp. Incr (MM/MIN) %s",prn_val((*software).a_speed_inc*60));
           }
        }
      if((*software).a_units==RAD)
        {if((*software).a_time==SEC)
           {  sprintf(item[13],"<Aux> Fast Jog (RAD/SEC)   %s",prn_val((*software).fjog_a));
              sprintf(item[17],"<Aux> Slow Jog (RAD/SEC)   %s",prn_val((*software).sjog_a));
              sprintf(item[19],"<Aux>F/R Sp. Incr(RAD/SEC) %s",prn_val((*software).a_speed_inc));
           }
         else
           {  sprintf(item[13],"<Aux> Fast Jog (RAD/MIN)   %s",prn_val((*software).fjog_a*60));
              sprintf(item[17],"<Aux> Slow Jog (RAD/MIN)   %s",prn_val((*software).sjog_a*60));
              sprintf(item[19],"<Aux>F/R Sp. Incr(RAD/MIN) %s",prn_val((*software).a_speed_inc*60));
           }
        }
      if((*software).a_units==DEG)
        {if((*software).a_time==SEC)
           {  sprintf(item[13],"<Aux> Fast Jog (DEG/SEC)   %s",prn_val((*software).fjog_a));
              sprintf(item[17],"<Aux> Slow Jog (DEG/SEC)   %s",prn_val((*software).sjog_a));
              sprintf(item[19],"<Aux>F/R Sp. Incr(DEG/SEC) %s",prn_val((*software).a_speed_inc));
           }
         else
           {  sprintf(item[13],"<Aux> Fast Jog (DEG/MIN)   %s",prn_val((*software).fjog_a*60));
              sprintf(item[17],"<Aux> Slow Jog (DEG/MIN)   %s",prn_val((*software).sjog_a*60));
              sprintf(item[19],"<Aux>F/R Sp. Incr(DEG/MIN) %s",prn_val((*software).a_speed_inc*60));
           }
        }
      if((*software).update_after==ON)
           sprintf(item[20], "Update Display Only After Move  ON");
      else sprintf(item[20], "Update Display Only After Move OFF");

      for(i=0;i<21;i++) {gotoxy(4,i+3); cprintf("%s",item[i]);}
      while (1)
        {textcolor(WHITE); gotoxy(4,curnt+3); textbackground(BLUE);
         cprintf("%s",item[curnt]); ch=getch();
         textcolor(BLACK);
         if (ch == 13 || ch == 32)
           {gotoxy(4,curnt+3); textbackground(GREEN);
            cprintf("%s",item[curnt]); textbackground(CYAN);
            change=TRUE;
            break;
           }
         gotoxy(4,curnt+3); textbackground(CYAN);
         cprintf("%s",item[curnt]);
         if (ch == 27) return change;
         if (ch > 0) continue;
         ch = getch();
         switch (ch)
           {case 72 : --curnt; break;  //up arrow
            case 80 : ++curnt; break;  //down arrow
            case 81 : curnt=21; break;  //pg dn
            case 73 : curnt=0; break;  //pg up

            case 59 :
              switch(curnt)
                {case 0: help(24); break;
                 case 1: help(25); break;
                 case 2: help(26); break;
                 case 3: help(27); break;
                 case 4: help(28); break;
                 case 5: case 6: case 7: case 8: help(29); break;
                 case 9: help(30); break;
                 case 10: case 11: case 12: case 13:
                 case 14: case 15: case 16: case 17: help(31); break;
                 case 18: case 19: help(32); break;
                 case 20: help(16); break;
                }
           }
         if(curnt<0) curnt=0;
         if(curnt>20) curnt=20;
        }

      switch(curnt)
        {case 0: if((*software).time==MIN) (*software).time=SEC;
                 else(*software).time=MIN; break;
         case 1: if((*software).a_time==MIN) (*software).a_time=SEC;
                 else(*software).a_time=MIN; break;
         case 2: if((*software).units==MM) change_units(hardware, software, IN, (*software).a_units);
                 else change_units(hardware, software, MM, (*software).a_units); break;
         case 3: if((*software).a_label=='W')
                   {(*software).a_label='A';
                    temp1=(*software).a_units;
                    if(temp2==DEG) (*software).a_units=DEG;
                    else (*software).a_units=RAD;
                    break;
                   }
                 if((*software).a_label=='A')
                   {(*software).a_label='C';
                    break;
                   }
                 if((*software).a_label=='C')
                   {(*software).a_label='W';
                    temp2=(*software).a_units;
                    if(temp1==IN) (*software).a_units=IN;
                    else (*software).a_units=MM;
                    break;
                   }
         case 4: if((*software).a_units==MM) change_units(hardware, software, (*software).units, IN);
                 else if((*software).a_units==IN) change_units(hardware, software, (*software).units, MM);
                 else if((*software).a_units==DEG) change_units(hardware, software, (*software).units, RAD);
                 else if((*software).a_units==RAD) change_units(hardware, software, (*software).units, DEG);
                 break;
         case 5:
         case 6:
         case 7:
         case 8:
            double_box(30,15,50,20, BLUE,WHITE,WHITE);
            gotoxy(4,3); cprintf("Enter New Value");
            _setcursortype(_NORMALCURSOR);
            gotoxy(10,4);
            if((i=get_string3(string))==ESC || i==NULL)
              {_setcursortype(_NOCURSOR);
               break;
              }
            _setcursortype(_NOCURSOR);
            if(curnt==5) sprintf((*software).io1_label,"%s",string);
            if(curnt==6) sprintf((*software).io2_label,"%s",string);
            if(curnt==7) sprintf((*software).io3_label,"%s",string);
            if(curnt==8) sprintf((*software).io4_label,"%s",string);
            break;

// --------------------------------------------------------------------------------------------------------------------

//         case 9: if((*software).invert_arrows==ON) (*software).invert_arrows=OFF;
//                 else (*software).invert_arrows=ON; break;


			case 9 :


      while(1)

         {double_box(31,10,51,24, BLUE,WHITE,WHITE);
	      gotoxy (1,1);  cprintf("   Jog Keys Config");
         gotoxy (7,3);  cprintf("%c",27);
         gotoxy (10,3); cprintf("%c",26);
         gotoxy (13,3); cprintf("%c",24);
         gotoxy (16,3); cprintf("%c",25);
         curnt2=0;

         for(i=0;i<8;i++) {gotoxy(4,i+5); cprintf("%s",item2[i]);}

          while(1)
          	{
            	textcolor(BLUE); gotoxy(4,curnt2+5); textbackground(WHITE);
		         cprintf("%s",item2[curnt2]); ch=getch();
      		   textcolor(WHITE); gotoxy(4,curnt2+5); textbackground(BLUE);
		         cprintf("%s",item2[curnt2]);

         if ((ch == 13 || ch == 32)) {(*software).invert_arrows=(curnt2); change=TRUE; break;}
         if (ch == 27) break;
         if (ch > 0) continue;
         ch = getch();
         switch (ch)
           		{case 72 : --curnt2; break;  //up arrow
                case 80 : ++curnt2; break;  //down arrow
            	 case 81 : curnt2=7; break;  //pg dn
            	 case 73 : curnt2=0; break;  //pg up
                case 59 : help(51); break;                     //f1
          		}
         if (curnt2 < 0) curnt2=0;
         if (curnt2 > 7) curnt2=7;
            } break;
        		}

           break;
//      temp_config=*hardware;



//----------------------------------------------------------------------------------------------------------------------

         case 10:
         case 11:
         case 12:
         case 13:
         case 14:
         case 15:
         case 16:
         case 17:
         case 18:
         case 19:
            double_box(30,5,50,10, BLUE,WHITE,WHITE);
            gotoxy(4,3); cprintf("Enter New Value");
            _setcursortype(_NORMALCURSOR);
            gotoxy(8,4);
            if((i=get_value(&value))==ESC || i==NULL)
              {_setcursortype(_NOCURSOR);
               break;
              }
            _setcursortype(_NOCURSOR);
            if((*software).time==SEC)
              {if(curnt==10) (*software).fjog_x=value;
               if(curnt==11) (*software).fjog_y=value;
               if(curnt==12) (*software).fjog_z=value;
               if(curnt==14) (*software).sjog_x=value;
               if(curnt==15) (*software).sjog_y=value;
               if(curnt==16) (*software).sjog_z=value;
               if(curnt==18) (*software).speed_inc=value;}
            else
              {if(curnt==10) (*software).fjog_x=value/60;
               if(curnt==11) (*software).fjog_y=value/60;
               if(curnt==12) (*software).fjog_z=value/60;
               if(curnt==14) (*software).sjog_x=value/60;
               if(curnt==15) (*software).sjog_y=value/60;
               if(curnt==16) (*software).sjog_z=value/60;
               if(curnt==18) (*software).speed_inc=value/60;}
            if((*software).a_time==SEC)
              {if(curnt==13) (*software).fjog_a=value;
               if(curnt==17) (*software).sjog_a=value;
               if(curnt==19) (*software).a_speed_inc=value;}
            else
              {if(curnt==13) (*software).fjog_a=value/60;
               if(curnt==17) (*software).sjog_a=value/60;
               if(curnt==19) (*software).a_speed_inc=value/60;}
         case 20:
            if(curnt==20)
              {if((*software).update_after==ON) {(*software).update_after=OFF; (*software).dt=(*software).dt*2;}
               else {(*software).update_after=ON; (*software).dt=(*software).dt/2;}
              }
            //reset maximum velocities
            if((*hardware).x_per_step/2<(*software).dt*(*hardware).vel_x) {(*hardware).vel_x=(*hardware).x_per_step/(2*(*software).dt); warning=TRUE;}
            if((*hardware).y_per_step/2<(*software).dt*(*hardware).vel_y) {(*hardware).vel_y=(*hardware).y_per_step/(2*(*software).dt); warning=TRUE;}
            if((*hardware).z_per_step/2<(*software).dt*(*hardware).vel_z) {(*hardware).vel_z=(*hardware).z_per_step/(2*(*software).dt); warning=TRUE;}
            if((*hardware).a_per_step/2<(*software).dt*(*hardware).vel_a) {(*hardware).vel_a=(*hardware).a_per_step/(2*(*software).dt); warning=TRUE;}

            //check and reset other speed settings
            if((*hardware).h_spd_x>(*hardware).vel_x) {(*hardware).h_spd_x=(*hardware).vel_x; warning=TRUE;}
            if((*hardware).h_spd_y>(*hardware).vel_y) {(*hardware).h_spd_y=(*hardware).vel_y; warning=TRUE;}
            if((*hardware).h_spd_z>(*hardware).vel_z) {(*hardware).h_spd_z=(*hardware).vel_z; warning=TRUE;}
            if((*hardware).h_spd_a>(*hardware).vel_a) {(*hardware).h_spd_a=(*hardware).vel_a; warning=TRUE;}
            if((*software).fjog_x>(*hardware).vel_x) {(*software).fjog_x=(*hardware).vel_x; warning=TRUE;}
            if((*software).fjog_y>(*hardware).vel_y) {(*software).fjog_y=(*hardware).vel_y; warning=TRUE;}
            if((*software).fjog_z>(*hardware).vel_z) {(*software).fjog_z=(*hardware).vel_z; warning=TRUE;}
            if((*software).fjog_a>(*hardware).vel_a) {(*software).fjog_a=(*hardware).vel_a; warning=TRUE;}
            if((*software).sjog_x>(*hardware).min_vel_x) {(*software).sjog_x=(*hardware).min_vel_x; warning=TRUE;}
            if((*software).sjog_y>(*hardware).min_vel_y) {(*software).sjog_y=(*hardware).min_vel_y; warning=TRUE;}
            if((*software).sjog_z>(*hardware).min_vel_z) {(*software).sjog_z=(*hardware).min_vel_z; warning=TRUE;}
            if((*software).sjog_a>(*hardware).min_vel_a) {(*software).sjog_a=(*hardware).min_vel_a; warning=TRUE;}

            if(warning==TRUE)
              {box(22,19,59,24, RED,BLACK,WHITE,WHITE);
               gotoxy(4,3); cprintf("Speed or Speeds Exceed Max Value");
               gotoxy(4,4); cprintf("Max Value Will Be Used <Any Key>");
               getch(); warning=FALSE;}
            break;
        }
     }
}

int home(struct hard_setup *hardware, struct soft_setup *software)
{
   static char item[16][35];
   int ch, i, curnt=0, change=FALSE, warning=FALSE;
   float value;

   while(1)
     {window(21,1,60,25);
      textbackground(CYAN);
      clrscr();
      box(21,1,60,20, CYAN,BLACK,WHITE,BLACK);
      window(21,1,60,25);
      gotoxy(15,1); cprintf("<Esc> To Exit");
      if((*software).units==IN)
        {sprintf(item[8], "<X> Debounce Distance (IN) %s",prn_val((*hardware).debo_x));
         sprintf(item[9], "<Y> Debounce Distance (IN) %s",prn_val((*hardware).debo_y));
         sprintf(item[10],"<Z> Debounce Distance (IN) %s",prn_val((*hardware).debo_z));
         sprintf(item[12],"<X> Working Length (IN)    %s",prn_val((*hardware).len_x));
         sprintf(item[13],"<Y> Working Length (IN)    %s",prn_val((*hardware).len_y));
         sprintf(item[14],"<Z> Working Length (IN)    %s",prn_val((*hardware).len_z));
         if((*software).time==SEC)
           {sprintf(item[4], "<X> Home Speed (IN/SEC)    %s",prn_val((*hardware).h_spd_x));
            sprintf(item[5], "<Y> Home Speed (IN/SEC)    %s",prn_val((*hardware).h_spd_y));
            sprintf(item[6], "<Z> Home Speed (IN/SEC)    %s",prn_val((*hardware).h_spd_z));
           }
         else
           {sprintf(item[4], "<X> Home Speed (IN/MIN)    %s",prn_val((*hardware).h_spd_x*60));
            sprintf(item[5], "<Y> Home Speed (IN/MIN)    %s",prn_val((*hardware).h_spd_y*60));
            sprintf(item[6], "<Z> Home Speed (IN/MIN)    %s",prn_val((*hardware).h_spd_z*60));
           }
        }
      else
        {sprintf(item[8], "<X> Debounce Distance (MM) %s",prn_val((*hardware).debo_x));
         sprintf(item[9], "<Y> Debounce Distance (MM) %s",prn_val((*hardware).debo_y));
         sprintf(item[10],"<Z> Debounce Distance (MM) %s",prn_val((*hardware).debo_z));
         sprintf(item[12],"<X> Working Length (MM)    %s",prn_val((*hardware).len_x));
         sprintf(item[13],"<Y> Working Length (MM)    %s",prn_val((*hardware).len_y));
         sprintf(item[14],"<Z> Working Length (MM)    %s",prn_val((*hardware).len_z));
         if((*software).time==SEC)
           {sprintf(item[4], "<X> Home Speed (MM/SEC)    %s",prn_val((*hardware).h_spd_x));
            sprintf(item[5], "<Y> Home Speed (MM/SEC)    %s",prn_val((*hardware).h_spd_y));
            sprintf(item[6], "<Z> Home Speed (MM/SEC)    %s",prn_val((*hardware).h_spd_z));
           }
         else
           {sprintf(item[4], "<X> Home Speed (MM/MIN)    %s",prn_val((*hardware).h_spd_x*60));
            sprintf(item[5], "<Y> Home Speed (MM/MIN)    %s",prn_val((*hardware).h_spd_y*60));
            sprintf(item[6], "<Z> Home Speed (MM/MIN)    %s",prn_val((*hardware).h_spd_z*60));
           }
        }
      if((*software).a_units==IN)
        {sprintf(item[11],"<Aux>Debounce Distance(IN) %s",prn_val((*hardware).debo_a));
         sprintf(item[15],"<Aux> Working Length (IN)  %s",prn_val((*hardware).len_a));
         if((*software).a_time==SEC)
           {sprintf(item[7],"<Aux> Home Speed (IN/SEC)  %s",prn_val((*hardware).h_spd_a));}
         else
           {sprintf(item[7],"<Aux> Home Speed (IN/MIN)  %s",prn_val((*hardware).h_spd_a*60));}
        }
      if((*software).a_units==MM)
        {sprintf(item[11],"<Aux>Debounce Distance(MM) %s",prn_val((*hardware).debo_a));
         sprintf(item[15],"<Aux> Working Length (MM)  %s",prn_val((*hardware).len_a));
         if((*software).a_time==SEC)
           {sprintf(item[7],"<Aux> Home Speed (MM/SEC)  %s",prn_val((*hardware).h_spd_a));}
         else
           {sprintf(item[7],"<Aux> Home Speed (MM/MIN)  %s",prn_val((*hardware).h_spd_a*60));}
        }
      if((*software).a_units==DEG)
        {sprintf(item[11],"<Aux> Debounce Sector(DEG) %s",prn_val((*hardware).debo_a));
         sprintf(item[15],"<Aux> Working Sector (DEG) %s",prn_val((*hardware).len_a));
         if((*software).a_time==SEC)
           {sprintf(item[7],"<Aux> Home Speed (DEG/SEC) %s",prn_val((*hardware).h_spd_a));}
         else
           {sprintf(item[7],"<Aux> Home Speed (DEG/MIN) %s",prn_val((*hardware).h_spd_a*60));}
        }
      if((*software).a_units==RAD)
        {sprintf(item[11],"<Aux> Debounce Sector(RAD) %s",prn_val((*hardware).debo_a));
         sprintf(item[15],"<Aux> Working Sector (RAD) %s",prn_val((*hardware).len_a));
         if((*software).a_time==SEC)
           {sprintf(item[7],"<Aux> Home Speed (RAD/SEC) %s",prn_val((*hardware).h_spd_a));}
         else
           {sprintf(item[7],"<Aux> Home Speed (RAD/MIN) %s",prn_val((*hardware).h_spd_a*60));}
        }
      if((*software).home_x==PLUS)
           sprintf(item[0],"<X> Home Direction        POSITIVE");
      else sprintf(item[0],"<X> Home Direction        NEGATIVE");
      if((*software).home_y==PLUS)
           sprintf(item[1],"<Y> Home Direction        POSITIVE");
      else sprintf(item[1],"<Y> Home Direction        NEGATIVE");
      if((*software).home_z==PLUS)
           sprintf(item[2],"<Z> Home Direction        POSITIVE");
      else sprintf(item[2],"<Z> Home Direction        NEGATIVE");
      if((*software).home_a==PLUS)
           sprintf(item[3],"<Aux> Home Direction      POSITIVE");
      else sprintf(item[3],"<Aux> Home Direction      NEGATIVE");

      for(i=0;i<16;i++) {gotoxy(4,i+3); cprintf("%s",item[i]);}
      while (1)
        {textcolor(WHITE); gotoxy(4,curnt+3); textbackground(BLUE);
         cprintf("%s",item[curnt]); ch=getch();
         textcolor(BLACK);
         if (ch == 13 || ch == 32)
           {gotoxy(4,curnt+3); textbackground(GREEN);
            cprintf("%s",item[curnt]); textbackground(CYAN);
            change=TRUE;
            break;
           }
         gotoxy(4,curnt+3); textbackground(CYAN);
         cprintf("%s",item[curnt]);
         if (ch == 27) return change;
         if (ch > 0) continue;
         ch = getch();
         switch (ch)
           {case 72 : --curnt; break;  //up arrow
            case 80 : ++curnt; break;  //down arrow
            case 81 : curnt=16; break;  //pg dn
            case 73 : curnt=0; break;  //pg up

            case 59 :
              switch(curnt)
                {case 0: case 1: case 2: case 3: help(33); break;
                 case 4: case 5: case 6: case 7: help(34); break;
                 case 8: case 9: case 10: case 11: help(35); break;
                 case 12: case 13: case 14: case 15: help(36); break;
                }
           }
         if(curnt<0) curnt=0;
         if(curnt>15) curnt=15;
        }

      if(curnt==0)
        {if((*software).home_x==PLUS) (*software).home_x=MINUS;
         else (*software).home_x=PLUS;}
      if(curnt==1)
        {if((*software).home_y==PLUS) (*software).home_y=MINUS;
         else (*software).home_y=PLUS;}
      if(curnt==2)
        {if((*software).home_z==PLUS) (*software).home_z=MINUS;
         else (*software).home_z=PLUS;}
      if(curnt==3)
        {if((*software).home_a==PLUS) (*software).home_a=MINUS;
         else (*software).home_a=PLUS;}
      if(curnt>=4)
        {if(curnt>=10 && curnt<=20) double_box(30,5,50,10, BLUE,WHITE,WHITE);
         else double_box(30,15,50,20, BLUE,WHITE,WHITE);
         gotoxy(4,3); cprintf("Enter New Value");
         _setcursortype(_NORMALCURSOR);
         gotoxy(8,4);
         if((i=get_value(&value))!=ESC && i!=NULL)
           {_setcursortype(_NOCURSOR);
            if(curnt==8) (*hardware).debo_x=value;
            if(curnt==9) (*hardware).debo_y=value;
            if(curnt==10) (*hardware).debo_z=value;
            if(curnt==11) (*hardware).debo_a=value;
            if(curnt==12) (*hardware).len_x=value;
            if(curnt==13) (*hardware).len_y=value;
            if(curnt==14) (*hardware).len_z=value;
            if(curnt==15) (*hardware).len_a=value;
            if((*software).time==SEC)
              {if(curnt==4) if(value!=0) (*hardware).h_spd_x=value;
               if(curnt==5) if(value!=0) (*hardware).h_spd_y=value;
               if(curnt==6) if(value!=0) (*hardware).h_spd_z=value;
              }
            else
              {if(curnt==4) if(value!=0) (*hardware).h_spd_x=value/60;
               if(curnt==5) if(value!=0) (*hardware).h_spd_y=value/60;
               if(curnt==6) if(value!=0) (*hardware).h_spd_z=value/60;
              }
            if((*software).a_time==SEC)
              {if(curnt==7) if(value!=0) (*hardware).h_spd_a=value;}
            else
              {if(curnt==7) if(value!=0) (*hardware).h_spd_a=value/60;}

            //check and reset other speed settings
            if((*hardware).h_spd_x>(*hardware).vel_x) {(*hardware).h_spd_x=(*hardware).vel_x; warning=TRUE;}
            if((*hardware).h_spd_y>(*hardware).vel_y) {(*hardware).h_spd_y=(*hardware).vel_y; warning=TRUE;}
            if((*hardware).h_spd_z>(*hardware).vel_z) {(*hardware).h_spd_z=(*hardware).vel_z; warning=TRUE;}
            if((*hardware).h_spd_a>(*hardware).vel_a) {(*hardware).h_spd_a=(*hardware).vel_a; warning=TRUE;}
            if(warning==TRUE)
              {box(22,19,59,24, RED,BLACK,WHITE,WHITE);
               gotoxy(4,3); cprintf("Speed or Speeds Exceed Max Value");
               gotoxy(4,4); cprintf("Max Value Will Be Used <Any Key>");
               getch(); warning=FALSE;}
            }
         else _setcursortype(_NOCURSOR);
        }
     }
}

int calibration(struct hard_setup *hardware, struct soft_setup *software)
{
   static char item[20][35];
   int ch, i, curnt=0, change=FALSE, warning=FALSE;
   float value;

   while(1)
     {window(21,1,60,25);
      textbackground(CYAN);
      clrscr();
      box(21,1,60,20, CYAN,BLACK,WHITE,BLACK);
      window(21,1,60,25);
      gotoxy(15,1); cprintf("<Esc> TO EXIT");
      if((*software).units==IN)
        {      sprintf(item[0], "<X> Backlash Value (IN)    %s",prn_val((*hardware).back_x));
               sprintf(item[1], "<Y> Backlash Value (IN)    %s",prn_val((*hardware).back_y));
               sprintf(item[2], "<Z> Backlash Value (IN)    %s",prn_val((*hardware).back_z));
               sprintf(item[4], "<X> Steps Per Inch         %s",prn_val(1/(*hardware).x_per_step));
               sprintf(item[5], "<Y> Steps Per Inch         %s",prn_val(1/(*hardware).y_per_step));
               sprintf(item[6], "<Z> Steps Per Inch         %s",prn_val(1/(*hardware).z_per_step));
         if((*software).time==SEC)
           {   sprintf(item[8], "<X> Max Velocity (IN/SEC)  %s",prn_val((*hardware).vel_x));
               sprintf(item[9], "<Y> Max Velocity (IN/SEC)  %s",prn_val((*hardware).vel_y));
               sprintf(item[10],"<Z> Max Velocity (IN/SEC)  %s",prn_val((*hardware).vel_z));
           }
         else
           {   sprintf(item[8], "<X> Max Velocity (IN/MIN)  %s",prn_val((*hardware).vel_x*60));
               sprintf(item[9], "<Y> Max Velocity (IN/MIN)  %s",prn_val((*hardware).vel_y*60));
               sprintf(item[10],"<Z> Max Velocity (IN/MIN)  %s",prn_val((*hardware).vel_z*60));
           }
               sprintf(item[12],"<X> Max Accel (FT/SEC^2)   %s",prn_val((*hardware).accel_x/12));
               sprintf(item[13],"<Y> Max Accel (FT/SEC^2)   %s",prn_val((*hardware).accel_y/12));
               sprintf(item[14],"<Z> Max Accel (FT/SEC^2)   %s",prn_val((*hardware).accel_z/12));
               sprintf(item[16],"<X> Max Stop Distance (IN) %s",prn_val((*hardware).vel_x*(*hardware).vel_x/(2*(*hardware).accel_x)));
               sprintf(item[17],"<Y> Max Stop Distance (IN) %s",prn_val((*hardware).vel_y*(*hardware).vel_y/(2*(*hardware).accel_y)));
               sprintf(item[18],"<Z> Max Stop Distance (IN) %s",prn_val((*hardware).vel_z*(*hardware).vel_z/(2*(*hardware).accel_z)));
        }
      else
        {      sprintf(item[0], "<X> Backlash Distance (MM) %s",prn_val((*hardware).back_x));
               sprintf(item[1], "<Y> Backlash Distance (MM) %s",prn_val((*hardware).back_y));
               sprintf(item[2], "<Z> Backlash Distance (MM) %s",prn_val((*hardware).back_z));
               sprintf(item[4], "<X> Steps Per Millimeter   %s",prn_val(1/(*hardware).x_per_step));
               sprintf(item[5], "<Y> Steps Per Millimeter   %s",prn_val(1/(*hardware).y_per_step));
               sprintf(item[6], "<Z> Steps Per Millimeter   %s",prn_val(1/(*hardware).z_per_step));
         if((*software).time==SEC)
           {   sprintf(item[8], "<X> Max Velocity (MM/SEC)  %s",prn_val((*hardware).vel_x));
               sprintf(item[9], "<Y> Max Velocity (MM/SEC)  %s",prn_val((*hardware).vel_y));
               sprintf(item[10],"<Z> Max Velocity (MM/SEC)  %s",prn_val((*hardware).vel_z));
           }
         else
           {   sprintf(item[8], "<X> Max Velocity (MM/MIN)  %s",prn_val((*hardware).vel_x*60));
               sprintf(item[9], "<Y> Max Velocity (MM/MIN)  %s",prn_val((*hardware).vel_y*60));
               sprintf(item[10],"<Z> Max Velocity (MM/MIN)  %s",prn_val((*hardware).vel_z*60));
           }
               sprintf(item[12],"<X> Max Accel (M/SEC^2)    %s",prn_val((*hardware).accel_x*.001));
               sprintf(item[13],"<Y> Max Accel (M/SEC^2)    %s",prn_val((*hardware).accel_y*.001));
               sprintf(item[14],"<Z> Max Accel (M/SEC^2)    %s",prn_val((*hardware).accel_z*.001));
               sprintf(item[16],"<X> Max Stop Distance (MM) %s",prn_val((*hardware).vel_x*(*hardware).vel_x/(2*(*hardware).accel_x)));
               sprintf(item[17],"<Y> Max Stop Distance (MM) %s",prn_val((*hardware).vel_y*(*hardware).vel_y/(2*(*hardware).accel_y)));
               sprintf(item[18],"<Z> Max Stop Distance (MM) %s",prn_val((*hardware).vel_z*(*hardware).vel_z/(2*(*hardware).accel_z)));
        }
      if((*software).a_units==IN)
        {      sprintf(item[3], "<Aux>Backlash Distance(IN) %s",prn_val((*hardware).back_a));
               sprintf(item[7], "<Aux> Steps Per Inch       %s",prn_val(1/(*hardware).a_per_step));
         if((*software).a_time==SEC)
               sprintf(item[11],"<Aux> Max Velocity(IN/SEC) %s",prn_val((*hardware).vel_a));
         else  sprintf(item[11],"<Aux> Max Velocity(IN/MIN) %s",prn_val((*hardware).vel_a*60));
               sprintf(item[15],"<Aux> Max Accel (FT/SEC^2) %s",prn_val((*hardware).accel_a/12));
               sprintf(item[19],"<Aux>Max Stop Distance(IN) %s",prn_val((*hardware).vel_a*(*hardware).vel_a/(2*(*hardware).accel_a)));
        }
      if((*software).a_units==MM)
        {      sprintf(item[3], "<Aux>Backlash Distance(MM) %s",prn_val((*hardware).back_a));
               sprintf(item[7], "<Aux> Steps Per Millimeter %s",prn_val(1/(*hardware).a_per_step));
         if((*software).a_time==SEC)
               sprintf(item[11],"<Aux> Max Velocity(MM/SEC) %s",prn_val((*hardware).vel_a));
         else  sprintf(item[11],"<Aux> Max Velocity(MM/MIN) %s",prn_val((*hardware).vel_a*60));
               sprintf(item[15],"<Aux> Max Accel (M/SEC^2)  %s",prn_val((*hardware).accel_a*.001));
               sprintf(item[19],"<Aux> Max Stop Angle (MM)  %s",prn_val((*hardware).vel_a*(*hardware).vel_a/(2*(*hardware).accel_a)));
        }
      if((*software).a_units==RAD)
        {      sprintf(item[3], "<Aux> Backlash Angle (RAD) %s",prn_val((*hardware).back_a));
               sprintf(item[7], "<Aux> Steps Per Radian     %s",prn_val(1/(*hardware).a_per_step));
         if((*software).a_time==SEC)
               sprintf(item[11],"<Aux>Max Velocity(RAD/SEC) %s",prn_val((*hardware).vel_a));
         else  sprintf(item[11],"<Aux>Max Velocity(RAD/MIN) %s",prn_val((*hardware).vel_a*60));
               sprintf(item[15],"<Aux> Max Accel(RAD/SEC^2) %s",prn_val((*hardware).accel_a));
               sprintf(item[19],"<Aux> Max Stop Angle(RAD)  %s",prn_val((*hardware).vel_a*(*hardware).vel_a/(2*(*hardware).accel_a)));
        }
      if((*software).a_units==DEG)
        {      sprintf(item[3], "<Aux> Backlash Angle (DEG) %s",prn_val((*hardware).back_a));
               sprintf(item[7], "<Aux> Steps Per Degree     %s",prn_val(1/(*hardware).a_per_step));
         if((*software).a_time==SEC)
               sprintf(item[11],"<Aux>Max Velocity(DEG/SEC) %s",prn_val((*hardware).vel_a));
         else  sprintf(item[11],"<Aux>Max Velocity(DEG/MIN) %s",prn_val((*hardware).vel_a*60));
               sprintf(item[15],"<Aux> Max Accel(DEG/SEC^2) %s",prn_val((*hardware).accel_a));
               sprintf(item[19],"<Aux> Max Stop Angle(DEG)  %s",prn_val((*hardware).vel_a*(*hardware).vel_a/(2*(*hardware).accel_a)));
        }

      for(i=0;i<16;i++) {gotoxy(4,i+3); cprintf("%s",item[i]);}
      textcolor(YELLOW); for(i=16;i<20;i++) {gotoxy(4,i+5); cprintf("%s",item[i]);} textcolor(BLUE);
      while (1)
        {textcolor(WHITE); gotoxy(4,curnt+3); textbackground(BLUE);
         cprintf("%s",item[curnt]); ch=getch();
         if (ch == 13 || ch == 32)
           {gotoxy(4,curnt+3); textbackground(GREEN);
            cprintf("%s",item[curnt]); textbackground(CYAN);
            change=TRUE;
            break;
           }
         gotoxy(4,curnt+3); textbackground(CYAN); textcolor(BLACK);
         cprintf("%s",item[curnt]);
         if (ch == 27) return change;
         if (ch > 0) continue;
         ch = getch();
         switch (ch)
           {case 72 : --curnt; break;  //up arrow
            case 80 : ++curnt; break;  //down arrow
            case 81 : curnt=16; break;  //pg dn
            case 73 : curnt=0; break;  //pg up

            case 59 :
              switch(curnt)
                {case 0: case 1: case 2: case 3: help(37); break;
                 case 4: case 5: case 6: case 7: help(38); break;
                 case 8: case 9: case 10: case 11: help(39); break;
                 case 12: case 13: case 14: case 15: help(40); break;
                }
           }
         if(curnt<0) curnt=0;
         if(curnt>15) curnt=15;
        }

      if(curnt>=8 && curnt<=15) double_box(30,3,50,8, BLUE,WHITE,WHITE);
      else double_box(30,12,50,17, BLUE,WHITE,WHITE);
      gotoxy(4,3); cprintf("Enter New Value");
      _setcursortype(_NORMALCURSOR);
      gotoxy(8,4);
      if((i=get_value(&value))!=ESC && i!=NULL)
        {_setcursortype(_NOCURSOR);
         if(curnt==0) {if(value>.000009) (*hardware).back_x=value; else (*hardware).back_x=0;}
         if(curnt==1) {if(value>.000009) (*hardware).back_y=value; else (*hardware).back_y=0;}
         if(curnt==2) {if(value>.000009) (*hardware).back_z=value; else (*hardware).back_z=0;}
         if(curnt==3) {if(value>.000009) (*hardware).back_a=value; else (*hardware).back_a=0;}
         if(curnt==4 && value>.000009) (*hardware).x_per_step=1/value;
         if(curnt==5 && value>.000009) (*hardware).y_per_step=1/value;
         if(curnt==6 && value>.000009) (*hardware).z_per_step=1/value;
         if(curnt==7 && value>.000009) (*hardware).a_per_step=1/value;
         if((*software).time==SEC)
           {if(curnt==8 && value>.000009) (*hardware).vel_x=value;
            if(curnt==9 && value>.000009) (*hardware).vel_y=value;
            if(curnt==10 && value>.000009) (*hardware).vel_z=value;
           }
         else
           {if(curnt==8 && value>.000009) (*hardware).vel_x=value/60;
            if(curnt==9 && value>.000009) (*hardware).vel_y=value/60;
            if(curnt==10 && value>.000009) (*hardware).vel_z=value/60;
           }
         if((*software).a_time==SEC)
           {if(curnt==11 && value>.000009) (*hardware).vel_a=value;}
         else
           {if(curnt==11 && value>.000009) (*hardware).vel_a=value/60;}
         if((*software).units==IN)
           {if(curnt==12 && value>.000009) (*hardware).accel_x=value*12;
            if(curnt==13 && value>.000009) (*hardware).accel_y=value*12;
            if(curnt==14 && value>.000009) (*hardware).accel_z=value*12;
           }
         else
           {if(curnt==12 && value>.000009) (*hardware).accel_x=value*1000;
            if(curnt==13 && value>.000009) (*hardware).accel_y=value*1000;
            if(curnt==14 && value>.000009) (*hardware).accel_z=value*1000;
           }
         if((*software).a_units==RAD || (*software).a_units==DEG) if(curnt==15) if(value!=0) (*hardware).accel_a=value;
         if((*software).a_units==MM) if(curnt==15) if(value>.000009) (*hardware).accel_a=value*1000;
         if((*software).a_units==IN) if(curnt==15) if(value>.000009) (*hardware).accel_a=value*12;

         //reset maximum velocities
         if((*hardware).x_per_step/2<(*software).dt*(*hardware).vel_x)
           {(*hardware).vel_x=(*hardware).x_per_step/(2*(*software).dt); warning=TRUE;}
         if((*hardware).y_per_step/2<(*software).dt*(*hardware).vel_y)
           {(*hardware).vel_y=(*hardware).y_per_step/(2*(*software).dt); warning=TRUE;}
         if((*hardware).z_per_step/2<(*software).dt*(*hardware).vel_z)
           {(*hardware).vel_z=(*hardware).z_per_step/(2*(*software).dt); warning=TRUE;}
         if((*hardware).a_per_step/2<(*software).dt*(*hardware).vel_a)
           {(*hardware).vel_a=(*hardware).a_per_step/(2*(*software).dt); warning=TRUE;}

         //reset minimum velocity
         (*hardware).min_vel_x=sqrt((*hardware).accel_x*(*hardware).x_per_step);
         (*hardware).min_vel_y=sqrt((*hardware).accel_y*(*hardware).y_per_step);
         (*hardware).min_vel_z=sqrt((*hardware).accel_z*(*hardware).z_per_step);
         (*hardware).min_vel_a=sqrt((*hardware).accel_a*(*hardware).a_per_step);

         //check and reset other speed settings
         if((*hardware).h_spd_x>(*hardware).vel_x) (*hardware).h_spd_x=(*hardware).vel_x;
         if((*hardware).h_spd_y>(*hardware).vel_y) (*hardware).h_spd_y=(*hardware).vel_y;
         if((*hardware).h_spd_z>(*hardware).vel_z) (*hardware).h_spd_z=(*hardware).vel_z;
         if((*hardware).h_spd_a>(*hardware).vel_a) (*hardware).h_spd_a=(*hardware).vel_a;
         if((*software).fjog_x>(*hardware).vel_x) (*software).fjog_x=(*hardware).vel_x;
         if((*software).fjog_y>(*hardware).vel_y) (*software).fjog_y=(*hardware).vel_y;
         if((*software).fjog_z>(*hardware).vel_z) (*software).fjog_z=(*hardware).vel_z;
         if((*software).fjog_a>(*hardware).vel_a) (*software).fjog_a=(*hardware).vel_a;
         if((*software).sjog_x>(*hardware).min_vel_x) (*software).sjog_x=(*hardware).min_vel_x;
         if((*software).sjog_y>(*hardware).min_vel_y) (*software).sjog_y=(*hardware).min_vel_y;
         if((*software).sjog_z>(*hardware).min_vel_z) (*software).sjog_z=(*hardware).min_vel_z;
         if((*software).sjog_a>(*hardware).min_vel_a) (*software).sjog_a=(*hardware).min_vel_a;

         if(warning==TRUE)
              {box(22,19,59,24, RED,BLACK,WHITE,WHITE);
               gotoxy(4,3); cprintf("Speed or Speeds Exceed Max Value");
               gotoxy(4,4); cprintf("Max Value Will Be Used <Any Key>");
               getch(); warning=FALSE;}
        }
      else _setcursortype(_NOCURSOR);
     }
}

void change_units(struct hard_setup *hardware, struct soft_setup *software, int units, int a_units)
{
   if((*software).units==IN && units==MM)
     {(*software).units=MM;
      (*hardware).x_per_step=(*hardware).x_per_step*25.4;
      (*hardware).y_per_step=(*hardware).y_per_step*25.4;
      (*hardware).z_per_step=(*hardware).z_per_step*25.4;
      (*hardware).accel_x=(*hardware).accel_x*25.4;
      (*hardware).accel_y=(*hardware).accel_y*25.4;
      (*hardware).accel_z=(*hardware).accel_z*25.4;
      (*hardware).vel_x=(*hardware).vel_x*25.4;
      (*hardware).vel_y=(*hardware).vel_y*25.4;
      (*hardware).vel_z=(*hardware).vel_z*25.4;
      (*hardware).h_spd_x=(*hardware).h_spd_x*25.4;
      (*hardware).h_spd_y=(*hardware).h_spd_y*25.4;
      (*hardware).h_spd_z=(*hardware).h_spd_z*25.4;
      (*hardware).back_x=(*hardware).back_x*25.4;
      (*hardware).back_y=(*hardware).back_y*25.4;
      (*hardware).back_z=(*hardware).back_z*25.4;
      (*hardware).debo_x=(*hardware).debo_x*25.4;
      (*hardware).debo_y=(*hardware).debo_y*25.4;
      (*hardware).debo_z=(*hardware).debo_z*25.4;
      (*hardware).len_x=(*hardware).len_x*25.4;
      (*hardware).len_y=(*hardware).len_y*25.4;
      (*hardware).len_z=(*hardware).len_z*25.4;
      (*hardware).min_vel_x=(*hardware).min_vel_x*25.4;
      (*hardware).min_vel_y=(*hardware).min_vel_y*25.4;
      (*hardware).min_vel_z=(*hardware).min_vel_z*25.4;
      (*software).speed_inc=(*software).speed_inc*25.4;
      (*software).fjog_x=(*software).fjog_x*25.4;
      (*software).fjog_y=(*software).fjog_y*25.4;
      (*software).fjog_z=(*software).fjog_z*25.4;
      (*software).sjog_x=(*software).sjog_x*25.4;
      (*software).sjog_y=(*software).sjog_y*25.4;
      (*software).sjog_z=(*software).sjog_z*25.4;
     }
   else if((*software).units==MM && units==IN)
     {(*software).units=IN;
      (*hardware).x_per_step=(*hardware).x_per_step/25.4;
      (*hardware).y_per_step=(*hardware).y_per_step/25.4;
      (*hardware).z_per_step=(*hardware).z_per_step/25.4;
      (*hardware).accel_x=(*hardware).accel_x/25.4;
      (*hardware).accel_y=(*hardware).accel_y/25.4;
      (*hardware).accel_z=(*hardware).accel_z/25.4;
      (*hardware).vel_x=(*hardware).vel_x/25.4;
      (*hardware).vel_y=(*hardware).vel_y/25.4;
      (*hardware).vel_z=(*hardware).vel_z/25.4;
      (*hardware).h_spd_x=(*hardware).h_spd_x/25.4;
      (*hardware).h_spd_y=(*hardware).h_spd_y/25.4;
      (*hardware).h_spd_z=(*hardware).h_spd_z/25.4;
      (*hardware).back_x=(*hardware).back_x/25.4;
      (*hardware).back_y=(*hardware).back_y/25.4;
      (*hardware).back_z=(*hardware).back_z/25.4;
      (*hardware).debo_x=(*hardware).debo_x/25.4;
      (*hardware).debo_y=(*hardware).debo_y/25.4;
      (*hardware).debo_z=(*hardware).debo_z/25.4;
      (*hardware).len_x=(*hardware).len_x/25.4;
      (*hardware).len_y=(*hardware).len_y/25.4;
      (*hardware).len_z=(*hardware).len_z/25.4;
      (*hardware).min_vel_x=(*hardware).min_vel_x/25.4;
      (*hardware).min_vel_y=(*hardware).min_vel_y/25.4;
      (*hardware).min_vel_z=(*hardware).min_vel_z/25.4;
      (*software).speed_inc=(*software).speed_inc/25.4;
      (*software).fjog_x=(*software).fjog_x/25.4;
      (*software).fjog_y=(*software).fjog_y/25.4;
      (*software).fjog_z=(*software).fjog_z/25.4;
      (*software).sjog_x=(*software).sjog_x/25.4;
      (*software).sjog_y=(*software).sjog_y/25.4;
      (*software).sjog_z=(*software).sjog_z/25.4;
     }
   if((*software).a_units==IN && a_units==MM)
     {(*software).a_units=MM;
      (*hardware).a_per_step=(*hardware).a_per_step*25.4;
      (*hardware).accel_a=(*hardware).accel_a*25.4;
      (*hardware).vel_a=(*hardware).vel_a*25.4;
      (*hardware).h_spd_a=(*hardware).h_spd_a*25.4;
      (*hardware).back_a=(*hardware).back_a*25.4;
      (*hardware).debo_a=(*hardware).debo_a*25.4;
      (*hardware).len_a=(*hardware).len_a*25.4;
      (*hardware).min_vel_a=(*hardware).min_vel_a*25.4;
      (*software).a_speed_inc=(*software).a_speed_inc*25.4;
      (*software).fjog_a=(*software).fjog_a*25.4;
      (*software).sjog_a=(*software).sjog_a*25.4;
      }
    else if((*software).a_units==MM && a_units==IN)
      {(*software).a_units=IN;
       (*hardware).a_per_step=(*hardware).a_per_step/25.4;
       (*hardware).accel_a=(*hardware).accel_a/25.4;
       (*hardware).vel_a=(*hardware).vel_a/25.4;
       (*hardware).h_spd_a=(*hardware).h_spd_a/25.4;
       (*hardware).back_a=(*hardware).back_a/25.4;
       (*hardware).debo_a=(*hardware).debo_a/25.4;
       (*hardware).len_a=(*hardware).len_a/25.4;
       (*hardware).min_vel_a=(*hardware).min_vel_a/25.4;
       (*software).a_speed_inc=(*software).a_speed_inc/25.4;
       (*software).fjog_a=(*software).fjog_a/25.4;
       (*software).sjog_a=(*software).sjog_a/25.4;
      }
    if((*software).a_units==RAD && a_units==DEG)
      {(*software).a_units=DEG;
       (*hardware).a_per_step=(*hardware).a_per_step*57.29578;
       (*hardware).accel_a=(*hardware).accel_a*57.29578;
       (*hardware).vel_a=(*hardware).vel_a*57.29578;
       (*hardware).h_spd_a=(*hardware).h_spd_a*57.29578;
       (*hardware).back_a=(*hardware).back_a*57.29578;
       (*hardware).debo_a=(*hardware).debo_a*57.29578;
       (*hardware).len_a=(*hardware).len_a*57.29578;
       (*hardware).min_vel_a=(*hardware).min_vel_a*57.29578;
       (*software).a_speed_inc=(*software).a_speed_inc*57.29578;
       (*software).fjog_a=(*software).fjog_a*57.29578;
       (*software).sjog_a=(*software).sjog_a*57.29578;
      }
    else if((*software).a_units==DEG && a_units==RAD)
      {(*software).a_units=RAD;
       (*hardware).a_per_step=(*hardware).a_per_step/57.29578;
       (*hardware).accel_a=(*hardware).accel_a/57.29578;
       (*hardware).vel_a=(*hardware).vel_a/57.29578;
       (*hardware).h_spd_a=(*hardware).h_spd_a/57.29578;
       (*hardware).back_a=(*hardware).back_a/57.29578;
       (*hardware).debo_a=(*hardware).debo_a/57.29578;
       (*hardware).len_a=(*hardware).len_a/57.29578;
       (*hardware).min_vel_a=(*hardware).min_vel_a/57.29578;
       (*software).a_speed_inc=(*software).a_speed_inc*57.29578;
       (*software).fjog_a=(*software).fjog_a/57.29578;
       (*software).sjog_a=(*software).sjog_a/57.29578;
      }
}

int data_pin(int bit)
{
   if(bit==1) return 2;
   if(bit==2) return 3;
   if(bit==4) return 4;
   if(bit==8) return 5;
   if(bit==16) return 6;
   if(bit==32) return 7;
   if(bit==64) return 8;
   else return 9;
}

int status_pin(int bit)
{
   if(bit==8) return 15;
   if(bit==16) return 13;
   if(bit==32) return 12;
   if(bit==64) return 10;
   return 11;
}

int control_pin(int bit)
{
   if(bit==1) return 1;
   if(bit==2) return 14;
   if(bit==4) return 16;
   return 17;
}

void define_data(struct hard_setup *hardware, struct soft_setup *software)
{
   //define hardware parameters
   (*hardware).x_sbit         =   1;         //step bit numbers on data port
   (*hardware).y_sbit         =   2;
   (*hardware).z_sbit         =   4;
   (*hardware).a_sbit         =   8;
   (*hardware).x_dbit         =   16;        //direction bit numbers on data port
   (*hardware).y_dbit         =   32;
   (*hardware).z_dbit         =   64;
   (*hardware).a_dbit         =   128;
   (*hardware).x_lbit         =   8;         //limit switch bit numbers on status port
   (*hardware).y_lbit         =   16;
   (*hardware).z_lbit         =   32;
   (*hardware).a_lbit         =   64;
   (*hardware).e_bit          =   128;       //e-stop bit number on status port
   (*hardware).io1_bit        =   1;         //i/o bit numbers control port
   (*hardware).io2_bit        =   2;
   (*hardware).io3_bit        =   4;
   (*hardware).io4_bit        =   8;
   (*hardware).port           =   0x378;     //port address
   (*hardware).x_ltrip        =   HIGH;      //trip states of limit switches (high/low)
   (*hardware).y_ltrip        =   HIGH;
   (*hardware).z_ltrip        =   HIGH;
   (*hardware).a_ltrip        =   HIGH;
   (*hardware).io1_on         =   HIGH;      //on states of io switches (high/low)
   (*hardware).io2_on         =   HIGH;
   (*hardware).io3_on         =   HIGH;
   (*hardware).io4_on         =   HIGH;
   (*hardware).e_trip         =   HIGH;      //trip state of e-stop (high/low)
   (*hardware).x_pdir         =   HIGH;      //positive directions are associated with
   (*hardware).y_pdir         =   HIGH;      //              assigned value (high/low)
   (*hardware).z_pdir         =   HIGH;
   (*hardware).a_pdir         =   HIGH;
   (*hardware).x_per_step     =   .01;       //units per step
   (*hardware).y_per_step     =   .01;
   (*hardware).z_per_step     =   .006;
   (*hardware).a_per_step     =   .01;
   (*hardware).debo_x         =   .02;        //debounce values(units)
   (*hardware).debo_y         =   .02;
   (*hardware).debo_z         =   .02;
   (*hardware).debo_a         =   .02;
   (*hardware).back_x         =   0;          //backlash values(units)
   (*hardware).back_y         =   0;
   (*hardware).back_z         =   0;
   (*hardware).back_a         =   0;
   (*hardware).accel_x        =   100;        //max. acceleration (units per sec^2)
   (*hardware).accel_y        =   100;
   (*hardware).accel_z        =   100;
   (*hardware).accel_a        =   100;
   (*hardware).vel_x          =   3;          //maximum velocities
   (*hardware).vel_y          =   3;
   (*hardware).vel_z          =   1;
   (*hardware).vel_a          =   3;
   (*hardware).h_spd_x        =   1;          //homing velocities
   (*hardware).h_spd_y        =   1;
   (*hardware).h_spd_z        =   .5;
   (*hardware).h_spd_a        =   1;
   (*hardware).len_x          =   96;         //working length
   (*hardware).len_y          =   48;
   (*hardware).len_z          =   4.5;
   (*hardware).len_a          =   0;
   (*hardware).min_vel_x      =   sqrt((*hardware).accel_x*(*hardware).x_per_step);
   (*hardware).min_vel_y      =   sqrt((*hardware).accel_y*(*hardware).y_per_step);
   (*hardware).min_vel_z      =   sqrt((*hardware).accel_z*(*hardware).z_per_step);
   (*hardware).min_vel_a      =   sqrt((*hardware).accel_a*(*hardware).a_per_step);
   (*hardware).act_step       =   HIGH;

   //define software parameters
   (*software).dt             =   .0001;     //time change
   (*software).update_after   =   OFF;       //on/off (flips display on/off)
   (*software).display_x      =   ON;        //value display (on/off)
   (*software).display_y      =   ON;
   (*software).display_z      =   ON;
   (*software).display_a      =   OFF;
   (*software).display_s      =   ON;
   (*software).display_as     =   OFF;
   (*software).display_fr     =   ON;
   (*software).x_xpos         =   29;        //x screen position of value
   (*software).x_ypos         =   7;         //y screen position of value
   (*software).y_xpos         =   29;
   (*software).y_ypos         =   9;
   (*software).z_xpos         =   29;
   (*software).z_ypos         =   11;
   (*software).a_xpos         =   29;
   (*software).a_ypos         =   13;
   (*software).s_xpos         =   31;
   (*software).s_ypos         =   17;
   (*software).as_xpos        =   31;
   (*software).as_ypos        =   18;
   (*software).fr_xpos        =   31;
   (*software).fr_ypos        =   16;
   (*software).keyboard       =   ON;        //keyboard control (on/off)
   (*software).limit          =   OFF;       //limit switches (on/off)
   (*software).e_stop         =   OFF;       //e-stop switches (on/off)
   (*software).io1_cmm        =   OFF;       //use i/o bit in cmm mode (on/off)
   (*software).io2_cmm        =   OFF;
   (*software).io3_cmm        =   OFF;
   (*software).io4_cmm        =   OFF;
   (*software).time           =   SEC;       //time units (sec/min)
   (*software).a_time         =   SEC;       //auxiliary time units (sec/min)
   (*software).x_label        =   'X';       //labels
   (*software).y_label        =   'Y';
   (*software).z_label        =   'Z';
   (*software).a_label        =   'W';
   (*software).a_status       =   OFF;
   (*software).a_follow       =   INDEPENDANT;
   (*software).units          =   IN;        //units
   (*software).a_units        =   IN;        //auxiliary units
   (*software).invert_arrows  =   0;         //custom arrow keys
   (*software).home_x         =   MINUS;     //home positions
   (*software).home_y         =   MINUS;
   (*software).home_z         =   MINUS;
   (*software).home_a         =   MINUS;
   (*software).speed_inc      =   .1;        //speed increment per key touch (units per sec)
   (*software).a_speed_inc    =   .1;
   (*software).fjog_x         =   (*hardware).vel_x;        //fast jog speeds
   (*software).fjog_y         =   (*hardware).vel_y;
   (*software).fjog_z         =   (*hardware).vel_z;
   (*software).fjog_a         =   (*hardware).vel_a;
   (*software).sjog_x         =   (*hardware).min_vel_x;    //slow jog speeds
   (*software).sjog_y         =   (*hardware).min_vel_y;
   (*software).sjog_z         =   (*hardware).min_vel_z;
   (*software).sjog_a         =   (*hardware).min_vel_a;
   sprintf((*software).io1_label, "IO1");   //io labels
   sprintf((*software).io2_label, "IO2");
   sprintf((*software).io3_label, "IO3");
   sprintf((*software).io4_label, "IO4");
   sprintf((*software).password,  "password");
   sprintf((*software).file,      "<DEFAULT>");
}

void load_setup(struct hard_setup *hard_config, struct soft_setup *soft_config, char *file)
{
   static struct hard_setup hardware;
   static struct soft_setup software;
   int PORT, cancel=OFF, version=0, temp;
   char pathfile[30];
   FILE *ifp;

   hardware=*hard_config; software=*soft_config;

   if(strcmp(file,"SETUP.INI")==0) {if(NULL==(ifp = fopen (file,"rb"))) return;}
   else if(strcmp(file,"<DEFAULT>")==0) {if(NULL==(ifp = fopen ("DEFAULTS.DEF","rb"))) return;}
   else
     {sprintf(pathfile,"CONFIG\\%s",file);
      if(NULL==(ifp = fopen (pathfile,"rb"))) return;
     }
   fscanf(ifp, "%d", &version);
   if(version==1)
     {if(NULL==fscanf(ifp, "%d",    &hardware.x_sbit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.y_sbit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.z_sbit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.a_sbit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.x_dbit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.y_dbit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.z_dbit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.a_dbit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.x_lbit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.y_lbit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.z_lbit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.a_lbit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.e_bit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.io1_bit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.io2_bit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.io3_bit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.io4_bit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d", &PORT)) cancel=ON;
      if(PORT==1) hardware.port=0x378;
      if(PORT==2) hardware.port=0x278;
      if(PORT==3) hardware.port=0x3bc;

      //new software setting
      if(NULL==fscanf(ifp, "%d",    &software.update_after)) cancel=ON;

      if(NULL==fscanf(ifp, "%d",    &hardware.x_ltrip)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.y_ltrip)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.z_ltrip)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.a_ltrip)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.io1_on)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.io2_on)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.io3_on)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.io4_on)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.e_trip)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.x_pdir)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.y_pdir)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.z_pdir)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &hardware.a_pdir)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.x_per_step)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.y_per_step)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.z_per_step)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.a_per_step)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.accel_x)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.accel_y)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.accel_z)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.accel_a)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.debo_x)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.debo_y)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.debo_z)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.debo_a)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.back_x)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.back_y)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.back_z)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.back_a)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.vel_x)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.vel_y)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.vel_z)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.vel_a)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.h_spd_x)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.h_spd_y)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.h_spd_z)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.h_spd_a)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.len_x)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.len_y)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.len_z)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.len_a)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.min_vel_x)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.min_vel_y)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.min_vel_z)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &hardware.min_vel_a)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.a_status)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.a_follow)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.display_a)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.display_as)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.limit)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.e_stop)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.time)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.a_time)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.a_label)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.units)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.a_units)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.invert_arrows)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.home_x)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.home_y)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.home_z)) cancel=ON;
      if(NULL==fscanf(ifp, "%d",    &software.home_a)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &software.speed_inc)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &software.a_speed_inc)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &software.fjog_x)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &software.fjog_y)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &software.fjog_z)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &software.fjog_a)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &software.sjog_x)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &software.sjog_y)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &software.sjog_z)) cancel=ON;
      if(NULL==fscanf(ifp, "%f",    &software.sjog_a)) cancel=ON;
      if(NULL==fscanf(ifp, "%s",    software.io1_label)) cancel=ON;
      if(NULL==fscanf(ifp, "%s",    software.io2_label)) cancel=ON;
      if(NULL==fscanf(ifp, "%s",    software.io3_label)) cancel=ON;
      if(NULL==fscanf(ifp, "%s",    software.io4_label)) cancel=ON;
      if(NULL==fscanf(ifp, "%s",    software.password)) cancel=ON;
      if(NULL==fscanf(ifp, "%s",    software.file)) cancel=ON;

      if((temp=fscanf(ifp, "%d",  &hardware.act_step))==NULL || temp==EOF) hardware.act_step=HIGH;

      if(cancel==OFF)
        {//reset maximum velocities
         if(hardware.x_per_step/2<software.dt*hardware.vel_x) hardware.vel_x=hardware.x_per_step/(2*software.dt);
         if(hardware.y_per_step/2<software.dt*hardware.vel_y) hardware.vel_y=hardware.y_per_step/(2*software.dt);
         if(hardware.z_per_step/2<software.dt*hardware.vel_z) hardware.vel_z=hardware.z_per_step/(2*software.dt);
         if(hardware.a_per_step/2<software.dt*hardware.vel_a) hardware.vel_a=hardware.a_per_step/(2*software.dt);

         //reset minimum velocity
         hardware.min_vel_x=sqrt(hardware.accel_x*hardware.x_per_step);
         hardware.min_vel_y=sqrt(hardware.accel_y*hardware.y_per_step);
         hardware.min_vel_z=sqrt(hardware.accel_z*hardware.z_per_step);
         hardware.min_vel_a=sqrt(hardware.accel_a*hardware.a_per_step);

         //check and reset other speed settings
         if(hardware.h_spd_x>hardware.vel_x) hardware.h_spd_x=hardware.vel_x;
         if(hardware.h_spd_y>hardware.vel_y) hardware.h_spd_y=hardware.vel_y;
         if(hardware.h_spd_z>hardware.vel_z) hardware.h_spd_z=hardware.vel_z;
         if(hardware.h_spd_a>hardware.vel_a) hardware.h_spd_a=hardware.vel_a;
         if(software.fjog_x>hardware.vel_x) software.fjog_x=hardware.vel_x;
         if(software.fjog_y>hardware.vel_y) software.fjog_y=hardware.vel_y;
         if(software.fjog_z>hardware.vel_z) software.fjog_z=hardware.vel_z;
         if(software.fjog_a>hardware.vel_a) software.fjog_a=hardware.vel_a;
         if(software.sjog_x>hardware.min_vel_x) software.sjog_x=hardware.min_vel_x;
         if(software.sjog_y>hardware.min_vel_y) software.sjog_y=hardware.min_vel_y;
         if(software.sjog_z>hardware.min_vel_z) software.sjog_z=hardware.min_vel_z;
         if(software.sjog_a>hardware.min_vel_a) software.sjog_a=hardware.min_vel_a;

         *hard_config=hardware;
         *soft_config=software;
        }
     }
   fclose(ifp);
}

void save_setup(struct hard_setup *hard_config, struct soft_setup *soft_config, char *file)
{
   FILE *ofp;
   char pathfile[30];

   if (strcmp(file,"SETUP.INI")==0) ofp = fopen (file,"wb");
   else
     {sprintf(pathfile,"CONFIG\\%s",file);
      if(NULL==(ofp = fopen (pathfile,"wb"))) return;
     }
   fprintf(ofp, "1\n");  //version 1
   fprintf(ofp, "%d\n",    (*hard_config).x_sbit);
   fprintf(ofp, "%d\n",    (*hard_config).y_sbit);
   fprintf(ofp, "%d\n",    (*hard_config).z_sbit);
   fprintf(ofp, "%d\n",    (*hard_config).a_sbit);
   fprintf(ofp, "%d\n",    (*hard_config).x_dbit);
   fprintf(ofp, "%d\n",    (*hard_config).y_dbit);
   fprintf(ofp, "%d\n",    (*hard_config).z_dbit);
   fprintf(ofp, "%d\n",    (*hard_config).a_dbit);
   fprintf(ofp, "%d\n",    (*hard_config).x_lbit);
   fprintf(ofp, "%d\n",    (*hard_config).y_lbit);
   fprintf(ofp, "%d\n",    (*hard_config).z_lbit);
   fprintf(ofp, "%d\n",    (*hard_config).a_lbit);
   fprintf(ofp, "%d\n",    (*hard_config).e_bit);
   fprintf(ofp, "%d\n",    (*hard_config).io1_bit);
   fprintf(ofp, "%d\n",    (*hard_config).io2_bit);
   fprintf(ofp, "%d\n",    (*hard_config).io3_bit);
   fprintf(ofp, "%d\n",    (*hard_config).io4_bit);
   if((*hard_config).port==0x378) fprintf(ofp,"1\n");
   if((*hard_config).port==0x278) fprintf(ofp,"2\n");
   if((*hard_config).port==0x3bc) fprintf(ofp,"3\n");

   //new software setting
   fprintf(ofp, "%d\n",    (*soft_config).update_after);

   fprintf(ofp, "%d\n",    (*hard_config).x_ltrip);
   fprintf(ofp, "%d\n",    (*hard_config).y_ltrip);
   fprintf(ofp, "%d\n",    (*hard_config).z_ltrip);
   fprintf(ofp, "%d\n",    (*hard_config).a_ltrip);
   fprintf(ofp, "%d\n",    (*hard_config).io1_on);
   fprintf(ofp, "%d\n",    (*hard_config).io2_on);
   fprintf(ofp, "%d\n",    (*hard_config).io3_on);
   fprintf(ofp, "%d\n",    (*hard_config).io4_on);
   fprintf(ofp, "%d\n",    (*hard_config).e_trip);
   fprintf(ofp, "%d\n",    (*hard_config).x_pdir);
   fprintf(ofp, "%d\n",    (*hard_config).y_pdir);
   fprintf(ofp, "%d\n",    (*hard_config).z_pdir);
   fprintf(ofp, "%d\n",    (*hard_config).a_pdir);
   fprintf(ofp, "%e\n",    (*hard_config).x_per_step);
   fprintf(ofp, "%e\n",    (*hard_config).y_per_step);
   fprintf(ofp, "%e\n",    (*hard_config).z_per_step);
   fprintf(ofp, "%e\n",    (*hard_config).a_per_step);
   fprintf(ofp, "%e\n",    (*hard_config).accel_x);
   fprintf(ofp, "%e\n",    (*hard_config).accel_y);
   fprintf(ofp, "%e\n",    (*hard_config).accel_z);
   fprintf(ofp, "%e\n",    (*hard_config).accel_a);
   fprintf(ofp, "%e\n",    (*hard_config).debo_x);
   fprintf(ofp, "%e\n",    (*hard_config).debo_y);
   fprintf(ofp, "%e\n",    (*hard_config).debo_z);
   fprintf(ofp, "%e\n",    (*hard_config).debo_a);
   fprintf(ofp, "%e\n",    (*hard_config).back_x);
   fprintf(ofp, "%e\n",    (*hard_config).back_y);
   fprintf(ofp, "%e\n",    (*hard_config).back_z);
   fprintf(ofp, "%e\n",    (*hard_config).back_a);
   fprintf(ofp, "%e\n",    (*hard_config).vel_x);
   fprintf(ofp, "%e\n",    (*hard_config).vel_y);
   fprintf(ofp, "%e\n",    (*hard_config).vel_z);
   fprintf(ofp, "%e\n",    (*hard_config).vel_a);
   fprintf(ofp, "%e\n",    (*hard_config).h_spd_x);
   fprintf(ofp, "%e\n",    (*hard_config).h_spd_y);
   fprintf(ofp, "%e\n",    (*hard_config).h_spd_z);
   fprintf(ofp, "%e\n",    (*hard_config).h_spd_a);
   fprintf(ofp, "%e\n",    (*hard_config).len_x);
   fprintf(ofp, "%e\n",    (*hard_config).len_y);
   fprintf(ofp, "%e\n",    (*hard_config).len_z);
   fprintf(ofp, "%e\n",    (*hard_config).len_a);
   fprintf(ofp, "%e\n",    (*hard_config).min_vel_x);
   fprintf(ofp, "%e\n",    (*hard_config).min_vel_y);
   fprintf(ofp, "%e\n",    (*hard_config).min_vel_z);
   fprintf(ofp, "%e\n",    (*hard_config).min_vel_a);
   fprintf(ofp, "%d\n",    (*soft_config).a_status);
   fprintf(ofp, "%d\n",    (*soft_config).a_follow);
   fprintf(ofp, "%d\n",    (*soft_config).display_a);
   fprintf(ofp, "%d\n",    (*soft_config).display_as);
   fprintf(ofp, "%d\n",    (*soft_config).limit);
   fprintf(ofp, "%d\n",    (*soft_config).e_stop);
   fprintf(ofp, "%d\n",    (*soft_config).time);
   fprintf(ofp, "%d\n",    (*soft_config).a_time);
   fprintf(ofp, "%d\n",    (*soft_config).a_label);
   fprintf(ofp, "%d\n",    (*soft_config).units);
   fprintf(ofp, "%d\n",    (*soft_config).a_units);
   fprintf(ofp, "%d\n",    (*soft_config).invert_arrows);
   fprintf(ofp, "%d\n",    (*soft_config).home_x);
   fprintf(ofp, "%d\n",    (*soft_config).home_y);
   fprintf(ofp, "%d\n",    (*soft_config).home_z);
   fprintf(ofp, "%d\n",    (*soft_config).home_a);
   fprintf(ofp, "%e\n",    (*soft_config).speed_inc);
   fprintf(ofp, "%e\n",    (*soft_config).a_speed_inc);
   fprintf(ofp, "%e\n",    (*soft_config).fjog_x);
   fprintf(ofp, "%e\n",    (*soft_config).fjog_y);
   fprintf(ofp, "%e\n",    (*soft_config).fjog_z);
   fprintf(ofp, "%e\n",    (*soft_config).fjog_a);
   fprintf(ofp, "%e\n",    (*soft_config).sjog_x);
   fprintf(ofp, "%e\n",    (*soft_config).sjog_y);
   fprintf(ofp, "%e\n",    (*soft_config).sjog_z);
   fprintf(ofp, "%e\n",    (*soft_config).sjog_a);
   fprintf(ofp, "%s\n",    (*soft_config).io1_label);
   fprintf(ofp, "%s\n",    (*soft_config).io2_label);
   fprintf(ofp, "%s\n",    (*soft_config).io3_label);
   fprintf(ofp, "%s\n",    (*soft_config).io4_label);
   fprintf(ofp, "%s\n",    (*soft_config).password);
   fprintf(ofp, "%s\n",    (*soft_config).file);

   fprintf(ofp, "%d\n",    (*hard_config).act_step);

   fclose(ofp);
}

void load_screen_setup(struct pos *world, struct pos *pt, struct control *ctrl)
{
   static struct pos temp_world;
   static struct pos temp_pt;
   static struct control temp_ctrl;
   int cancel=OFF;
   FILE *ifp;

   temp_world=*world; temp_pt=*pt; temp_ctrl=*ctrl;

   if(NULL==(ifp = fopen ("SCREEN.INI","rb"))) return;
   if(NULL==fscanf(ifp, "%lf",    &temp_world.x_pos)) cancel=ON;
   if(NULL==fscanf(ifp, "%lf",    &temp_world.y_pos)) cancel=ON;
   if(NULL==fscanf(ifp, "%lf",    &temp_world.z_pos)) cancel=ON;
   if(NULL==fscanf(ifp, "%lf",    &temp_world.a_pos)) cancel=ON;
   if(NULL==fscanf(ifp, "%lf",    &temp_pt.x_pos)) cancel=ON;
   if(NULL==fscanf(ifp, "%lf",    &temp_pt.y_pos)) cancel=ON;
   if(NULL==fscanf(ifp, "%lf",    &temp_pt.z_pos)) cancel=ON;
   if(NULL==fscanf(ifp, "%lf",    &temp_pt.a_pos)) cancel=ON;
   if(NULL==fscanf(ifp, "%d",    &temp_ctrl.jog_type)) cancel=ON;
   if(NULL==fscanf(ifp, "%f",    &temp_ctrl.jog_inc)) cancel=ON;
   if(NULL==fscanf(ifp, "%f",    &temp_ctrl.frate)) cancel=ON;
   if(NULL==fscanf(ifp, "%d",    &temp_ctrl.cs)) cancel=ON;
   if(NULL==fscanf(ifp, "%d",    &temp_ctrl.pty)) cancel=ON;
   if(NULL==fscanf(ifp, "%d",    &temp_ctrl.cvv)) cancel=ON;
   if(cancel==OFF)
     {*world=temp_world;
      *pt=temp_pt;
      *ctrl=temp_ctrl;
     }
   fclose(ifp);
}

void save_screen_setup(struct pos *world, struct pos *pt, struct control *ctrl)
{
   FILE *ofp;

   if(NULL==(ofp = fopen ("SCREEN.INI","wb"))) return;
   fprintf(ofp, "%e\n",    (*world).x_pos);
   fprintf(ofp, "%e\n",    (*world).y_pos);
   fprintf(ofp, "%e\n",    (*world).z_pos);
   fprintf(ofp, "%e\n",    (*world).a_pos);
   fprintf(ofp, "%e\n",    (*pt).x_pos);
   fprintf(ofp, "%e\n",    (*pt).y_pos);
   fprintf(ofp, "%e\n",    (*pt).z_pos);
   fprintf(ofp, "%e\n",    (*pt).a_pos);
   fprintf(ofp, "%d\n",    (*ctrl).jog_type);
   fprintf(ofp, "%e\n",    (*ctrl).jog_inc);
   fprintf(ofp, "%e\n",    (*ctrl).frate);
   fprintf(ofp, "%d\n",    (*ctrl).cs);
   fprintf(ofp, "%d\n",    (*ctrl).pty);
   fprintf(ofp, "%d\n",    (*ctrl).cvv);
   fclose(ofp);
}
